package online.iizvv.controls;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpUtil;
import com.dd.plist.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import online.iizvv.pojo.Apple;
import online.iizvv.pojo.Authorize;
import online.iizvv.pojo.Device;
import online.iizvv.pojo.Package;
import online.iizvv.service.AppleServiceImpl;
import online.iizvv.service.DeviceServiceImpl;
import online.iizvv.service.PackageServiceImpl;
import online.iizvv.core.config.Config;
import online.iizvv.utils.FileManager;
import online.iizvv.utils.ITSUtils;
import online.iizvv.utils.Shell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @author :iizvv
 * @date :Created in 2019-06-26 20:39
 * @description:获取UDID
 * @modified By:
 * @version: 1.0
 */
@RestController
@Api(tags = {"获取UDID下载APP"})
@RequestMapping("/udid")
public class UDIDController {

    @Autowired
    private DeviceServiceImpl deviceService;

    @Autowired
    private AppleServiceImpl appleService;

    @Autowired
    private PackageServiceImpl packageService;

    @Autowired
    private FileManager  fileManager;

    @ApiOperation(value="/getUDID", notes="获取设备udid", produces = "application/json")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "id", value = "IPA id", required = true),
    })
    @PostMapping("/getUDID")
    public void getUDID(HttpServletResponse response, HttpServletRequest request, String id) throws UnsupportedEncodingException {
        response.setContentType("text/html;charset=UTF-8");
        long begin = System.currentTimeMillis();
        String ua = request.getHeader("User-Agent");
        System.out.println("当前时间: " + DateUtil.now() + "\n当前产品id: " + id + "\n当前用户User-Agent: " + ua);
        String itemService = null;
        try {
            request.setCharacterEncoding("UTF-8");
            //获取HTTP请求的输入流
            InputStream is = request.getInputStream();
            //已HTTP请求输入流建立一个BufferedReader对象
            BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
            StringBuilder sb = new StringBuilder();
            //读取HTTP请求内容
            String buffer = null;
            while ((buffer = br.readLine()) != null) {
                sb.append(buffer);
            }
            String xml = sb.toString().substring(sb.toString().indexOf("<?xml"), sb.toString().indexOf("</plist>")+8);
            NSDictionary parse = (NSDictionary) PropertyListParser.parse(xml.getBytes());
            String udid = (String) parse.get("UDID").toJavaObject();
            itemService = analyzeUDID(udid, id);
            System.out.println("itemService文件名为: " + itemService);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String redirect = Config.redirect + "/detail/" + id;
        if (itemService!=null) {
            String encode = "itms-services://?action=download-manifest&url=" + Config.aliTempHost + "/" + itemService;
            redirect += "?itemService=" + URLEncoder.encode(encode, "UTF-8" );
            packageService.updatePackageCountById(Integer.valueOf(id));
        }
        long end = System.currentTimeMillis();
        long result = (end - begin)/1000;
        System.out.println("自动签名执行耗时: " + result + "秒");
        response.setHeader("Location", redirect);
        response.setStatus(301);
    }

    /**
     * create by: iizvv
     * description: 分析UDID信息
     * create time: 2019-06-26 21:40
     *

     * @return void
     */
    String analyzeUDID(String udid, String id) {
        String itemService = null;
        Device device = deviceService.getDeviceByUDID(udid);
        if (device==null) {
            // 设备不存在于任何帐号下
            System.out.println("设备不存在");
            Apple apple = appleService.getBeUsableAppleAccount();
            if (apple==null) {
                // 没有找到合适的帐号
                System.out.println("没有找到合适的帐号");
            }else {
                // 找到合适的帐号
                Package pck = packageService.getPackageById(id);
                String resignature = insertDevice(udid, apple, pck.getLink());
                itemService = software(resignature, pck.getBundleIdentifier(), pck.getVersion(), pck.getName());
            }
        }else {
            // 设备存在
            Apple apple = appleService.getAppleAccountById(device.getAppleId());
            Package pck = packageService.getPackageById(id);
            String resignature = resignature(apple, device.getDeviceId(), pck.getLink());
            itemService = software(resignature, pck.getBundleIdentifier(), pck.getVersion(), pck.getName());
        }
        return itemService;
    }

    /**
     * create by: iizvv
     * description: 添加设备
     * create time: 2019-06-26 23:11
     *

     * @return String
     */
    String insertDevice(String udid, Apple apple, String link) {
        System.out.println("找到合适的帐号");
        // 发现可用账号
        String key = null;
        String devId = ITSUtils.insertDevice(udid, new Authorize(apple.getP8(), apple.getIss(), apple.getKid()));
        int i = deviceService.insertDevice(udid, apple.getId(), devId);
        if (i==1) {
            appleService.updateAppleAccountDevicesCount(apple.getId());
            key = resignature(apple, devId, link);
        }
        return key;
    }

    /**
      * create by: iizvv
      * description: 重签名
      * create time: 2019-07-06 08:42

      * @return String
      */
    String resignature(Apple apple, String devId, String appLink) {
        String key = null;
        // ResourceUtils.getURL("classpath:").getPath()
        String classPath = "/root/";
        long begin = System.currentTimeMillis();
        File mobileprovision = ITSUtils.insertProfile(apple, devId, classPath);
        long end = System.currentTimeMillis();
        long time = (end - begin)/1000;
        System.out.println("创建证书耗时: " + time + "秒");
        String command = null;
        if (mobileprovision==null) {
            System.out.println("文件创建失败");
        }else {
            System.out.println("文件创建成功");
            String appUrl = Config.vpcAliMainHost + "/" + appLink;
            HttpUtil.downloadFile(appUrl, classPath);
            System.out.println("ipa下载完成: " + appUrl);
            File app = new File(classPath+appLink);
            String p12Url = Config.vpcAliMainHost + "/" + apple.getP12();
            HttpUtil.downloadFile(p12Url, classPath);
            System.out.println("p12下载完成: " + p12Url);
            File p12 = new File(classPath+apple.getP12());
            // 调用本地shell脚本并传递必须参数
            command = "/root/ausign.sh " + app.getName() + " " +
                    p12.getName() + " " +
                    mobileprovision.getName();
            System.out.println("调用shell进行签名: " + command);
            try {
                begin = System.currentTimeMillis();
                boolean result = Shell.run(command);
                end = System.currentTimeMillis();
                time = (end - begin)/1000;
                System.out.println("签名脚本执行耗时: " + time + "秒");
                if (result) {
                    key = uploadIPA(app);
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            } finally {
                mobileprovision.delete();
                app.delete();
                p12.delete();
            }
        }
        return key;
    }

    /**
     * create by: iizvv
     * description: 上传IPA
     * create time: 2019-07-05 13:11

     * @return void
     */
    String uploadIPA(File file) {
        String objName = UUID.randomUUID().toString().replace("-", "")+".ipa";
        System.out.println("开始上传最终ipa文件, 文件名: " + objName);
        fileManager.uploadFile(file, objName);
        System.out.println("文件上传完成");
        file.delete();
        System.out.println("ipa文件删除: " + objName);
        return objName;
    }

    /**
      * create by: iizvv
      * description: 下载IPA的item-service
      * create time: 2019-07-06 10:34

      * @return
      */
    String software(String ipaUrl, String id, String version, String title) {
        ipaUrl = Config.aliTempHost + "/" + ipaUrl;
        System.out.println("ipaUrl: " + ipaUrl);
        String plist = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>  \n" +
                "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">  \n" +
                "<plist version=\"1.0\">  \n" +
                "<dict>  \n" +
                "    <key>items</key>  \n" +
                "    <array>  \n" +
                "        <dict>  \n" +
                "            <key>assets</key>  \n" +
                "            <array>  \n" +
                "                <dict>  \n" +
                "                    <key>kind</key>  \n" +
                "                    <string>software-package</string>  \n" +
                "                    <key>url</key>  \n" +
                "                    <string>"+ ipaUrl +"</string>  \n" +
                "                </dict>  \n" +
                "            </array>  \n" +
                "            <key>metadata</key>  \n" +
                "            <dict>  \n" +
                "                <key>bundle-identifier</key>  \n" +
                "                <string>"+ id +"</string>  \n" +
                "                <key>bundle-version</key>  \n" +
                "                <string>" + version + "</string>  \n" +
                "                <key>kind</key>  \n" +
                "                <string>software</string>  \n" +
                "                <key>title</key>  \n" +
                "                <string>" + title + "</string>  \n" +
                "            </dict>  \n" +
                "        </dict>  \n" +
                "    </array>  \n" +
                "</dict>  \n" +
                "</plist> ";
        String filePath = "itemService_" + UUID.randomUUID().toString().replace("-", "") +".plist";
        FileWriter writer = new FileWriter(filePath);
        writer.write(plist);
        String itemService = uploadItemService(writer.getFile());
        writer.getFile().delete();
        return itemService;
    }

    /**
     * create by: iizvv
     * description: 上传itemService
     * create time: 2019-07-04 11:18

     * @return plist名称
     */
    String uploadItemService(File file) {
        String objName = UUID.randomUUID().toString().replace("-", "")+".plist";
        fileManager.uploadFile(file, objName);
        return objName;
    }

}