package ai.pai.lensman.dslr;


import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.text.TextUtils;

import com.android.common.utils.LogHelper;

import java.util.Timer;
import java.util.TimerTask;

public class CameraService extends Service {

    private boolean isInitExecuted;
    private CameraInitTask cameraInitTask;

    private Timer photoCaptureTimer;
    private String sessionWorkingDirPath;
    private boolean isLastQueryReturned = true;

    public static final String ACTION_CAMERA_SERVICE_STATUS_CHANGE = "action.ai.pai.lensman.dslr.cameraservice";
    public static final String EXTRA_STATUS_PART = "status";
    public static final String EXTRA_DATA_PART = "data";

    public static final int MSG_CAMERA_INIT_SUCCESS = 8000;
    public static final int MSG_CAMERA_CONN_ERROR = 8001;
    public static final int MSG_CAMERA_NEW_PHOTO_FOUND = 8002;


    public static final String EXTRA_CMD = "cmd";
    public static final String EXTRA_SESSION_DIR = "session_dir";
    public static final int CMD_INIT_CAMERA_CONNECTION = 9000;
    public static final int CMD_EXIT_CAMERA_CONNECTION = 9001;
    public static final int CMD_START_CAPTURE_PHOTO = 9002;

    private static final String MSG_TYPE_CAMERA_ERROR = "camero error";//相机错误，可能是线松动了。先exit，然后重新init
    private static final String MSG_TYPE_NOT_INIT = "not init";  //需要初始化
    private static final String MSG_TYPE_TIME_OUT = "time out";  //继续调用waitforevent

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent!=null&&intent.getIntExtra(EXTRA_CMD,0)>0){
            int cmd = intent.getIntExtra(EXTRA_CMD,0);
            if(cmd == CMD_EXIT_CAMERA_CONNECTION){
                stopCameraService();
            }else if(cmd == CMD_INIT_CAMERA_CONNECTION){
                if(!isInitExecuted){
                    cameraInitTask = new CameraInitTask();
                    cameraInitTask.execute();
                }
            }else if(cmd == CMD_START_CAPTURE_PHOTO){
                if(isInitExecuted){
                    sessionWorkingDirPath = intent.getStringExtra(EXTRA_SESSION_DIR);
                    if(!TextUtils.isEmpty(sessionWorkingDirPath)){
                        startCapture();
                    }
                }
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    private void stopCameraService(){
        if(cameraInitTask!=null){
            cameraInitTask.cancel();
        }
        if(photoCaptureTimer !=null){
            photoCaptureTimer.cancel();
            photoCaptureTimer = null;
        }
        new CameraExitTask().execute();
        stopSelf();
        Process.killProcess(Process.myPid());
        System.exit(0);
    }

    class CameraInitTask extends AsyncTask<Void,Integer,Integer>{

        private boolean isCancelled = false;

        public void cancel(){
            isCancelled = true;
        }

        @Override
        protected Integer doInBackground(Void... params) {
            isInitExecuted = true;
             return  CameraJNIInterface.getInstance().java_mygpcamerainit();
        }

        @Override
        protected void onPostExecute(Integer result) {

            if(isCancelled){
                return;
            }
            if(result>=0){
                Bundle bundle = new Bundle();
                bundle.putInt(EXTRA_STATUS_PART,MSG_CAMERA_INIT_SUCCESS);
                sendCameraIntent(bundle);
            }else{
                Bundle bundle = new Bundle();
                bundle.putInt(EXTRA_STATUS_PART, MSG_CAMERA_CONN_ERROR);
                sendCameraIntent(bundle);
                stopCameraService();
            }
        }
    }

    class CameraExitTask extends AsyncTask<Void,Integer,Integer>{


        @Override
        protected Integer doInBackground(Void... params) {
            return  CameraJNIInterface.getInstance().java_mygpcameraexit();
        }

    }
    public void startCapture() {
        if(photoCaptureTimer !=null){
            photoCaptureTimer.cancel();
            photoCaptureTimer = null;
        }
        photoCaptureTimer = new Timer();
        photoCaptureTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                fetchPhotoTask();
            }
        },1000,10);
    }

    private void fetchPhotoTask(){
        if(!isLastQueryReturned){
            LogHelper.d("czy","fetchPhotoTask last query not finished,return ");
            return;
        }

        isLastQueryReturned = false;
        String eventMsg = CameraJNIInterface.getInstance().java_mygpcamerawaitforevent(sessionWorkingDirPath);
        LogHelper.d("czy","mygpcamerawaitforevent return result = "+eventMsg);
        if(eventMsg!=null && eventMsg.length()>0){
            if(MSG_TYPE_NOT_INIT.equalsIgnoreCase(eventMsg)||MSG_TYPE_CAMERA_ERROR.equalsIgnoreCase(eventMsg)){
                Bundle bundle = new Bundle();
                bundle.putInt(EXTRA_STATUS_PART, MSG_CAMERA_CONN_ERROR);
                sendCameraIntent(bundle);
                stopCameraService();
            }else if(MSG_TYPE_TIME_OUT.equalsIgnoreCase(eventMsg)){

            }else{
                String sub = eventMsg.substring(0,1);
                if(TextUtils.isDigitsOnly(sub)){
                    LogHelper.d("czy","fetchPhotoTask new photo found");
                    Bundle bundle = new Bundle();
                    bundle.putInt(EXTRA_STATUS_PART, MSG_CAMERA_NEW_PHOTO_FOUND);
                    bundle.putString(EXTRA_DATA_PART,eventMsg);
                    sendCameraIntent(bundle);
                }
            }
        }

        isLastQueryReturned = true;
    }

    private void sendCameraIntent(Bundle bundle){
        Intent intent = new Intent(ACTION_CAMERA_SERVICE_STATUS_CHANGE);
        intent.putExtras(bundle);
        sendBroadcast(intent);
    }

}
