package com.daxiang.core.mobile.android;

import com.android.ddmlib.*;
import com.daxiang.core.Device;
import com.daxiang.core.mobile.Mobile;
import com.daxiang.core.mobile.MobileChangeHandler;
import com.daxiang.core.mobile.MobileDevice;
import com.daxiang.core.mobile.android.scrcpy.Scrcpy;
import com.daxiang.core.mobile.android.stf.AdbKit;
import com.daxiang.core.mobile.android.stf.Minicap;
import com.daxiang.core.mobile.android.stf.MinicapInstaller;
import com.daxiang.core.mobile.android.stf.Minitouch;
import com.daxiang.core.mobile.android.stf.MinitouchInstaller;
import com.daxiang.core.mobile.appium.AppiumServer;
import com.daxiang.model.UploadFile;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Date;

/**
 * Created by jiangyitao.
 */
@Component
@Slf4j
public class AndroidDeviceChangeListener extends MobileChangeHandler implements AndroidDebugBridge.IDeviceChangeListener {

    // http://appium.github.io/appium/assets/ApiDemos-debug.apk
    private static final String APIDEMOS_APK = "vendor/apk/ApiDemos-debug.apk";

    @Override
    public void deviceConnected(IDevice device) {
        new Thread(() -> androidDeviceConnected(device)).start();
    }

    @Override
    public void deviceDisconnected(IDevice device) {
        new Thread(() -> mobileDisconnected(device.getSerialNumber())).start();
    }

    @Override
    public void deviceChanged(IDevice device, int changeMask) {
        // ignore
    }

    private void androidDeviceConnected(IDevice iDevice) {
        String mobileId = iDevice.getSerialNumber();
        log.info("[{}]已连接", mobileId);

        log.info("[{}]等待上线", mobileId);
        AndroidUtil.waitForMobileOnline(iDevice, 5 * 60);
        log.info("[{}]已上线", mobileId);

        mobileConnected(iDevice);
    }

    @Override
    protected MobileDevice initMobile(IDevice iDevice, AppiumServer appiumServer) throws Exception {
        String mobileId = iDevice.getSerialNumber();

        Mobile mobile = new Mobile();

        mobile.setPlatform(MobileDevice.PLATFORM_ANDROID);
        mobile.setCreateTime(new Date());
        mobile.setId(mobileId);
        mobile.setSystemVersion(AndroidUtil.getAndroidVersion(AndroidUtil.getSdkVersion(iDevice)));
        mobile.setName(AndroidUtil.getDeviceName(iDevice));
        mobile.setCpuInfo(AndroidUtil.getCpuInfo(iDevice));
        mobile.setMemSize(AndroidUtil.getMemSize(iDevice));
        mobile.setEmulator(iDevice.isEmulator() ? Mobile.EMULATOR : Mobile.REAL_MOBILE);

        String resolution = AndroidUtil.getResolution(iDevice); // 720x1280
        String[] res = resolution.split("x");
        mobile.setScreenWidth(Integer.parseInt(res[0]));
        mobile.setScreenHeight(Integer.parseInt(res[1]));

        AndroidDevice androidDevice = new AndroidDevice(mobile, iDevice, appiumServer);

        // 小于android5.0使用stf远程真机方案,否则使用scrcpy方案
        // 小于android5.0初始化driver需要指定app
        if (!androidDevice.greaterOrEqualsToAndroid5()) {
            log.info("[{}]开始安装minicap", mobileId);
            MinicapInstaller minicapInstaller = new MinicapInstaller(iDevice);
            minicapInstaller.install();
            log.info("[{}]安装minicap成功", mobileId);

            log.info("[{}]开始安装minitouch", mobileId);
            MinitouchInstaller minitouchInstaller = new MinitouchInstaller(iDevice);
            minitouchInstaller.install();
            log.info("[{}]安装minitouch成功", mobileId);

            // 安装一个测试apk,用于初始化appium driver
            log.info("[{}]开始安装{}", mobileId, APIDEMOS_APK);
            androidDevice.installApp(new File(APIDEMOS_APK));
            log.info("[{}]安装{}完成", mobileId, APIDEMOS_APK);
        }

        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setCapability("skipServerInstallation", false);
        caps.setCapability("skipDeviceInitialization", false);
        caps.setCapability("skipUnlock", false);
        caps.setCapability("skipLogcatCapture", false);

        log.info("[{}]开始初始化appium", mobileId);
        RemoteWebDriver driver = androidDevice.freshDriver(caps, true);
        log.info("[{}]初始化appium完成", mobileId);

        // 截图并上传到服务器
        UploadFile uploadFile = androidDevice.screenshotThenUploadToServer();
        mobile.setImgPath(uploadFile.getFilePath());

        driver.quit();

        return androidDevice;
    }

    @Override
    protected MobileDevice newMobile(IDevice iDevice, Mobile mobile, AppiumServer appiumServer) {
        return new AndroidDevice(mobile, iDevice, appiumServer);
    }

    @Override
    protected void reconnectToAgent(Device device, IDevice iDevice) {
        // 重连到agent 更新IDevice
        ((AndroidDevice) device).setIDevice(iDevice);
    }

    @Override
    protected void beforePutDeviceToHolder(Device device) {
        AndroidDevice androidDevice = (AndroidDevice) device;
        IDevice iDevice = androidDevice.getIDevice();

        androidDevice.setMinicap(new Minicap(iDevice));
        androidDevice.setMinitouch(new Minitouch(iDevice));
        androidDevice.setScrcpy(new Scrcpy(iDevice));
        androidDevice.setAdbKit(new AdbKit(androidDevice.getId()));
    }
}