/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.camera.activity;

import android.app.Activity;
import android.app.Instrumentation;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

import com.android.camera.CameraHolder;
import com.android.camera.CameraManager.CameraProxy;
import com.android.camera.Util;
import com.android.gallery3d.R;

import static com.google.testing.littlemock.LittleMock.mock;
import static com.google.testing.littlemock.LittleMock.doAnswer;
import static com.google.testing.littlemock.LittleMock.doReturn;
import static com.google.testing.littlemock.LittleMock.anyObject;
import com.google.testing.littlemock.AppDataDirGuesser;
import com.google.testing.littlemock.ArgumentCaptor;
import com.google.testing.littlemock.Captor;
import com.google.testing.littlemock.LittleMock;
import com.google.testing.littlemock.Mock;

import java.io.File;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.concurrent.Callable;


public class CameraTestCase<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
    protected CameraInfo mCameraInfo[];
    protected CameraProxy mMockCamera[];
    protected CameraInfo mOneCameraInfo[];
    protected CameraProxy mOneMockCamera[];
    private static Parameters mParameters;
    private byte[] mBlankJpeg;
    @Mock private CameraProxy mMockBackCamera;
    @Mock private CameraProxy mMockFrontCamera;
    @Captor private ArgumentCaptor<ShutterCallback> mShutterCallback;
    @Captor private ArgumentCaptor<PictureCallback> mRawPictureCallback;
    @Captor private ArgumentCaptor<PictureCallback> mJpegPictureCallback;
    @Captor private ArgumentCaptor<AutoFocusCallback> mAutoFocusCallback;
    Callable<Object> mAutoFocusCallable = new AutoFocusCallable();
    Callable<Object> mTakePictureCallable = new TakePictureCallable();

    private class TakePictureCallable implements Callable<Object> {
        @Override
        public Object call() throws Exception {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    readBlankJpeg();
                    Camera camera = mOneMockCamera[0].getCamera();
                    mShutterCallback.getValue().onShutter();
                    mRawPictureCallback.getValue().onPictureTaken(null, camera);
                    mJpegPictureCallback.getValue().onPictureTaken(mBlankJpeg, camera);
                }
            };
            // Probably need some delay. Make sure shutter callback is called
            // after onShutterButtonFocus(false).
            getActivity().findViewById(R.id.gl_root_view).postDelayed(runnable, 50);
            return null;
        }
   }

    private class AutoFocusCallable implements Callable<Object> {
        @Override
        public Object call() throws Exception {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    Camera camera = mOneMockCamera[0].getCamera();
                    mAutoFocusCallback.getValue().onAutoFocus(true, camera);
                }
            };
            // Need some delay. Otherwise, focus callback will be run before
            // onShutterButtonClick
            getActivity().findViewById(R.id.gl_root_view).postDelayed(runnable, 50);
            return null;
        }
   }

    public CameraTestCase(Class<T> activityClass) {
        super(activityClass);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        AppDataDirGuesser.setInstance(new AppDataDirGuesser() {
            @Override
            public File guessSuitableDirectoryForGeneratedClasses() {
                return getInstrumentation().getTargetContext().getCacheDir();
            }
        });
        AppDataDirGuesser.getsInstance().guessSuitableDirectoryForGeneratedClasses();
        LittleMock.initMocks(this);
        mCameraInfo = new CameraInfo[2];
        mCameraInfo[0] = new CameraInfo();
        mCameraInfo[0].facing = CameraInfo.CAMERA_FACING_BACK;
        mCameraInfo[1] = new CameraInfo();
        mCameraInfo[1].facing = CameraInfo.CAMERA_FACING_FRONT;
        mMockCamera = new CameraProxy[2];
        mMockCamera[0] = mMockBackCamera;
        mMockCamera[1] = mMockFrontCamera;
        doReturn(getParameters()).when(mMockCamera[0]).getParameters();
        doReturn(getParameters()).when(mMockCamera[1]).getParameters();

        mOneCameraInfo = new CameraInfo[1];
        mOneCameraInfo[0] = new CameraInfo();
        mOneCameraInfo[0].facing = CameraInfo.CAMERA_FACING_BACK;
        mOneMockCamera = new CameraProxy[1];
        mOneMockCamera[0] = mMockBackCamera;
        doReturn(getParameters()).when(mOneMockCamera[0]).getParameters();

        // Mock takePicture call.
        doAnswer(mTakePictureCallable).when(mMockBackCamera).takePicture(
                mShutterCallback.capture(), mRawPictureCallback.capture(),
                (PictureCallback) anyObject(), mJpegPictureCallback.capture());

        // Mock autoFocus call.
        doAnswer(mAutoFocusCallable).when(mMockBackCamera).autoFocus(
                mAutoFocusCallback.capture());
    }

    private void readBlankJpeg() {
        InputStream ins = getActivity().getResources().openRawResource(R.raw.blank);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        int size = 0;

        // Read the entire resource into a local byte buffer.
        byte[] buffer = new byte[1024];
        try {
            while((size = ins.read(buffer, 0, 1024)) >= 0){
                outputStream.write(buffer, 0, size);
            }
        } catch (IOException e) {
            // ignore
        } finally {
            Util.closeSilently(ins);
        }
        mBlankJpeg = outputStream.toByteArray();
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
        CameraHolder.injectMockCamera(null,  null);
    }

    protected void internalTestFailToConnect() throws Exception {
        CameraHolder.injectMockCamera(mCameraInfo, null);

        getActivity();
        Instrumentation inst = getInstrumentation();
        inst.waitForIdleSync();
        inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); // close dialog
    }

    protected void performClick(final int id) {
        Activity activity = getActivity();
        getInstrumentation().waitForIdleSync();
        assertNotNull(activity.findViewById(id));
        Instrumentation inst = getInstrumentation();
        inst.runOnMainSync(new Runnable() {
            @Override
            public void run() {
                View v = getActivity().findViewById(id);
                float x = (v.getLeft() + v.getRight()) / 2;
                float y = (v.getTop() + v.getBottom()) / 2;
                MotionEvent down = MotionEvent.obtain(0, 0,
                        MotionEvent.ACTION_DOWN, x, y, 0, 0, 0, 0, 0, 0, 0);
                MotionEvent up = MotionEvent.obtain(0, 0,
                        MotionEvent.ACTION_UP, x, y, 0, 0, 0, 0, 0, 0, 0);
                View parent = (View) v.getParent();
                parent.dispatchTouchEvent(down);
                parent.dispatchTouchEvent(up);
            }
        });
        inst.waitForIdleSync();
    }

    protected void assertViewNotExist(int id) {
        Activity activity = getActivity();
        getInstrumentation().waitForIdleSync();
        assertNull(activity.findViewById(id));
    }

    protected void assertViewNotVisible(int id) {
        Activity activity = getActivity();
        getInstrumentation().waitForIdleSync();
        View view = activity.findViewById(id);
        assertTrue(view.getVisibility() != View.VISIBLE);
    }

    protected static Parameters getParameters() {
        synchronized (CameraTestCase.class) {
            if (mParameters == null) {
                mParameters = android.hardware.Camera.getEmptyParameters();
                mParameters.unflatten("preview-format-values=yuv420sp,yuv420p,yuv422i-yuyv,yuv420p;" +
                        "preview-format=yuv420sp;" +
                        "preview-size-values=800x480;preview-size=800x480;" +
                        "picture-size-values=320x240;picture-size=320x240;" +
                        "jpeg-thumbnail-size-values=320x240,0x0;jpeg-thumbnail-width=320;jpeg-thumbnail-height=240;" +
                        "jpeg-thumbnail-quality=60;jpeg-quality=95;" +
                        "preview-frame-rate-values=30,15;preview-frame-rate=30;" +
                        "focus-mode-values=continuous-video,auto,macro,infinity,continuous-picture;focus-mode=auto;" +
                        "preview-fps-range-values=(15000,30000);preview-fps-range=15000,30000;" +
                        "scene-mode-values=auto,action,night;scene-mode=auto;" +
                        "flash-mode-values=off,on,auto,torch;flash-mode=off;" +
                        "whitebalance-values=auto,daylight,fluorescent,incandescent;whitebalance=auto;" +
                        "effect-values=none,mono,sepia;effect=none;" +
                        "zoom-supported=true;zoom-ratios=100,200,400;max-zoom=2;" +
                        "picture-format-values=jpeg;picture-format=jpeg;" +
                        "min-exposure-compensation=-30;max-exposure-compensation=30;" +
                        "exposure-compensation=0;exposure-compensation-step=0.1;" +
                        "horizontal-view-angle=40;vertical-view-angle=40;");
            }
        }
        return mParameters;
    }
}
