package com.lemenzo.gallery.tests;

import android.graphics.RectF;
import android.test.InstrumentationTestCase;
import android.view.accessibility.AccessibilityNodeInfo;

import com.lemenzo.gallery.editor.AnnotationOverlayView;
import com.lemenzo.gallery.editor.BitmapBudget;
import com.lemenzo.gallery.editor.AutoEnhanceAnalyzer;
import com.lemenzo.gallery.editor.CropOverlayView;
import com.lemenzo.gallery.manage.MediaFileManager;
import com.lemenzo.gallery.privacy.JpegSanitizer;
import com.lemenzo.gallery.smart.SmartCategoryClassifier;
import com.lemenzo.gallery.smart.VisualHeuristics;
import com.lemenzo.gallery.viewer.MotionPhotoXmpParser;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public final class GalleryRegressionTest extends InstrumentationTestCase {
    public void testFolderSanitization() {
        assertEquals("Family", MediaFileManager.sanitizeFolder(" /Family/ "));
        assertEquals("DCIM/Lemenzo/Family/", MediaFileManager.targetPath("Family"));
        assertEquals("Pictures/Family/", MediaFileManager.targetPath("Pictures/Family"));
        assertFalse(MediaFileManager.sanitizeFolder("../A*B").contains(".."));
    }

    public void testSmartCategoryTokens() {
        assertEquals("screenshots", SmartCategoryClassifier.searchToken(SmartCategoryClassifier.Category.SCREENSHOTS));
        assertEquals("raw", SmartCategoryClassifier.searchToken(SmartCategoryClassifier.Category.RAW));
        assertEquals("motion", SmartCategoryClassifier.searchToken(SmartCategoryClassifier.Category.MOTION_PHOTO));
        assertEquals("selfies", SmartCategoryClassifier.searchToken(SmartCategoryClassifier.Category.SELFIES));
    }

    public void testVerifiedMotionPhotoXmpParser() {
        String modern="<Camera:MotionPhoto=\"1\"/><Container:Item Item:Mime=\"video/mp4\" Item:Length=\"321\"/>";
        assertEquals(321L, MotionPhotoXmpParser.candidateVideoLength(modern));
        assertEquals(0L, MotionPhotoXmpParser.candidateVideoLength("<Camera:MotionPhoto=\"0\"/>"));
    }

    public void testBitmapBudgetNeverReturnsTinyUnsafeEdge() {
        int edge = BitmapBudget.safeDecodeMaxEdge(12000, 9000);
        assertTrue(edge == 0 || edge >= 2048);
    }

    public void testJpegSanitizerRemovesApp1AndKeepsScan() throws Exception {
        byte[] fake = new byte[] {
                (byte)0xff,(byte)0xd8,
                (byte)0xff,(byte)0xe1, 0, 6, 'E','X','I','F',
                (byte)0xff,(byte)0xda, 0, 2,
                1,2,3,4,(byte)0xff,(byte)0xd9
        };
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        JpegSanitizer.sanitize(new ByteArrayInputStream(fake), out);
        byte[] clean = out.toByteArray();
        assertTrue(clean.length < fake.length);
        for (int i=0;i+1<clean.length;i++) assertFalse((clean[i]&255)==0xff && (clean[i+1]&255)==0xe1);
        assertEquals(1, clean[6]);
    }

    public void testAutoEnhanceAndVisualHeuristics() {
        int[] dark = new int[256]; dark[35] = 1000;
        AutoEnhanceAnalyzer.Recommendation rec = AutoEnhanceAnalyzer.recommend(dark, 1000, 40, 40, 42, 8);
        assertTrue(rec.exposure > 0f);
        assertTrue(VisualHeuristics.looksLikeDocument(new VisualHeuristics.Stats(.70,.82,.08,.10)));
    }

    public void testCustomEditorViewsExposeAccessibilityActions() {
        CropOverlayView crop = new CropOverlayView(getInstrumentation().getTargetContext());
        crop.setContentDescription("Crop");
        AccessibilityNodeInfo cropInfo = AccessibilityNodeInfo.obtain();
        crop.onInitializeAccessibilityNodeInfo(cropInfo);
        assertTrue(cropInfo.getActionList().size() >= 6);
        cropInfo.recycle();
        assertNotNull(crop.getAccessibilityNodeProvider());
        assertNotNull(crop.getAccessibilityNodeProvider().createAccessibilityNodeInfo(1));

        AnnotationOverlayView annotation = new AnnotationOverlayView(getInstrumentation().getTargetContext());
        AccessibilityNodeInfo annotationInfo = AccessibilityNodeInfo.obtain();
        annotation.onInitializeAccessibilityNodeInfo(annotationInfo);
        assertTrue(annotationInfo.getActionList().size() >= 2);
        annotationInfo.recycle();
        annotation.performAccessibilityAction(0x01011001, null);
        assertNotNull(annotation.getAccessibilityNodeProvider());
        assertNotNull(annotation.getAccessibilityNodeProvider().createAccessibilityNodeInfo(1));
    }
}
