package com.xypower.mpapp.adb;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

import com.dev.devapi.api.SysApi;
import com.xypower.common.FilesUtils;
import com.xypower.common.MicroPhotoContext;
import com.xypower.mpapp.BuildConfig;
import com.xypower.mpapp.MicroPhotoService;
import com.xypower.mpapp.v2.Camera2VideoActivity;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import dadb.AdbKeyPair;
import dadb.AdbShellResponse;
import dadb.Dadb;

public class CameraAdb {
    private final String TAG = "CameraAdb";

    private Context mContext;
    private String mAppPath;
    private AdbKeyPair mAdbKeyPair;
    private String mDeviceIp = "127.0.0.1";
    private List<String> mTargetPaths = new ArrayList<>();
    private Runnable mRunnable;

    public List<String> getTargetPaths() {
        return mTargetPaths;
    }

    public void setCallback(Runnable runnable) {
        mRunnable = runnable;
    }

    public CameraAdb(Context context, String appPath) {

        mContext = context;
        mAppPath = appPath;

        try {
            File cameraPath = new File("/sdcard/DCIM/Camera/");
            FilenameFilter filter = new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return true;
                }
            };
            File[] files = cameraPath.listFiles(filter);

            for (File file : files) {
                if (file.lastModified() > 1722960000000L) {
                    file.delete();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        File file = new File( new File(appPath), "data/.keypair");
        if (!file.exists()) {
            file.mkdirs();
        }

        final File pubKeyFile = new File(file, "pub.key");
        final File priKeyFile = new File(file, "pri.key");
        if (!priKeyFile.exists() || !pubKeyFile.exists()) {
            AdbKeyPair.generate(priKeyFile, pubKeyFile);
        }

        mAdbKeyPair = AdbKeyPair.read(priKeyFile, pubKeyFile);
    }

    public void takePhoto(final int cameraId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                takePhotoImpl(cameraId);
            }
        }).start();
    }

    private void takePhotoImpl(final int cameraId) {

        long requestTime = System.currentTimeMillis() / 1000;
        takePhoto(cameraId == 1);
        long takingTime = System.currentTimeMillis() / 1000;
        sleep(1500);
        String path = movePhoto(false, requestTime, takingTime);
        if (!TextUtils.isEmpty(path)) {
            mTargetPaths.add(path);
        }
        sleep(100);
        SysApi.forceStopApp(mContext, "com.mediatek.camera");

        if (mRunnable != null) {
            mRunnable.run();
        }
    }

    private String movePhoto(boolean frontCamera, long requestTime, long takingTime) {

        String targetPath = null;
        String photoPath = mAppPath + "photos/";
        String photoFile = "IMG_" + Long.toHexString(requestTime).toUpperCase() + "_"
                + (frontCamera ? "2" : "1") + "_FE_0_" + Long.toHexString(requestTime).toUpperCase()
                + "_" + Long.toHexString(takingTime).toUpperCase() + ".jpg";

        File cameraPath = new File("/sdcard/DCIM/Camera/");

        boolean res = false;
        for (int idx = 0; idx < 10; idx++) {

            Optional<File> opFile = Arrays.stream(cameraPath.listFiles(File::isFile))
                .max((f1, f2) -> Long.compare(f1.lastModified(), f2.lastModified()));

            if (opFile.isPresent()) {
                File targetFile = new File(new File(photoPath), photoFile);
                try {
                    File srcFile = opFile.get();
                    if (BuildConfig.DEBUG) {
                        FilesUtils.copyFile(srcFile, targetFile);
                        res = true;
                    } else {
                        res = srcFile.renameTo(targetFile);
                    }
                    if (res) {
                        targetPath = targetFile.getAbsolutePath();
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            sleep(200);
        }

        if (!res) {
            Log.e(TAG, "Failed to copy photo from Camera");
        }

        return targetPath;
    }

    private void sleep(long timeout) {
        try {
            Thread.sleep(timeout);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    protected void takePhoto(final boolean frontCamera) {
        Dadb adb = Dadb.create(mDeviceIp, 5555, mAdbKeyPair);

        if (adb == null) {
            return;
        }

        Log.d(TAG, mDeviceIp + " Connected");
        boolean res = false;

        String[] cmds = {
                "content insert --uri content://settings/system --bind name:s:accelerometer_rotation --bind value:i:0",
                "content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:1",
                "am force-stop com.mediatek.camera",
                "wait 1000",
                "setprop mtk.camera.app.keycode.enable 1",
                "setprop mtk.camera.switch.camera.debug 1",
                "setprop mtk.camera.switch.id.debug back-1",
                "am start -a android.media.action.STILL_IMAGE_CAMERA" +
                        (frontCamera ? " --ez com.google.assistant.extra.USE_FRONT_CAMERA true" : "") + " -f " + Integer.toString(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP),
                "wait 3000",
                "input keyevent 27"};

        AdbShellResponse adbShellResponse = null;
        for (String cmd : cmds) {
            if (cmd.startsWith("wait ")) {
                try {
                    Thread.sleep(Long.parseLong(cmd.substring(5)));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                continue;
            }
            try {
                adbShellResponse = adb.shell(cmd);
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            Log.i(TAG, "CMD: " + cmd);
            if (adbShellResponse.getExitCode() == 0) {
                String[] lines = FilesUtils.splitLines(adbShellResponse.getAllOutput());
                for (String line : lines) {
                    Log.i(TAG, line);
                }
            }
        }
    }
}
