package online.iizvv.controls;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ZipUtil;
import com.dd.plist.NSDictionary;
import com.dd.plist.PropertyListFormatException;
import com.dd.plist.PropertyListParser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import online.iizvv.pojo.Package;
import online.iizvv.core.pojo.Result;
import online.iizvv.service.PackageServiceImpl;
import online.iizvv.core.config.Config;
import online.iizvv.utils.FileManager;
import online.iizvv.utils.Shell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.SAXException;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;

/**
 * @author :iizvv
 * @date :Created in 2019-06-28 15:08
 * @description:IPA包管理
 * @version: 1.0
 */
@RestController
@RequestMapping("/package")
@Api(tags = {"IPA包管理"})
public class PackageController {

    @Autowired
    private PackageServiceImpl packageService;

    @Autowired
    private FileManager fileManager;

    @ApiOperation(value = "/getAllPackage", notes = "获取全部IPA")
    @GetMapping("/getAllPackage")
    public Result<List<Package>> getAllPackage(HttpServletRequest request) {
        Result result = new Result();
        List<Package> allPackage = packageService.getAllPackage();
        for (Package aPackage : allPackage) {
            aPackage.setIcon(Config.aliMainHost + "/" + aPackage.getIcon());
            aPackage.setMobileconfig(Config.aliMainHost + "/" + aPackage.getMobileconfig());
        }
        result.setMsg("数据获取成功");
        result.setData(allPackage);
        result.setCode(1);
        return result;
    }


    @ApiOperation(value = "/uploadPackage", notes = "上传ipa", produces = "application/json")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "file", value = "ipa文件", required = true),
            @ApiImplicitParam(name = "summary", value = "简介")
    })
    @PostMapping("/uploadPackage")
    public Result uploadPackage(MultipartFile file, String summary) {
        Result result = new Result();
        if (file!=null) {
            String fileName = file.getOriginalFilename();
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
            if (suffix.equalsIgnoreCase("ipa")) {
                // 上传的文件为ipa文件
                try {
                    int i = analyze(file, summary);
                    if (i==1) {
                        result.setCode(1);
                        result.setMsg("ipa文件提交成功");
                    }else {
                        result.setMsg("ipa文件解析失败");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    result.setMsg("ipa解析失败");
                }
            }else {
                // 上传的文件非ipa文件
                result.setMsg("请检查文件类型");
            }
        }else {
            result.setMsg("文件不存在, 检查路径是否正确");
        }
        return result;
    }

    @ApiOperation(value = "/getPackageById", notes = "获取指定ipa")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "id", value = "ipaId", required = true)
    })
    @GetMapping("/getPackageById")
    public Result getPackageById(String id) {
        Result result = new Result();
        Package pck = packageService.getPackageById(id);
        if (pck==null) {
            result.setMsg("内容不存在");
        }else {
            pck.setIcon(Config.aliMainHost + "/" + pck.getIcon());
            pck.setMobileconfig(Config.aliMainHost + "/" + pck.getMobileconfig());
            result.setCode(1);
            result.setMsg("获取成功");
            result.setData(pck);
        }
        return result;
    }

    /**
      * create by: iizvv
      * description: 解析ipa
      * create time: 2019-06-28 15:59

      * @return void
      */
    int analyze(MultipartFile file, String summary) throws ParserConfigurationException, ParseException, SAXException, PropertyListFormatException, IOException {
        File excelFile = File.createTempFile(UUID.randomUUID().toString(), ".ipa");
        file.transferTo(excelFile);
        File ipa = ZipUtil.unzip(excelFile);
        File app = getAppFile(ipa);
        File info = new File(app.getAbsolutePath()+"/Info.plist");
        NSDictionary parse = (NSDictionary) PropertyListParser.parse(new FileReader(info).readBytes());
        String name = parse.get("CFBundleName").toString();
        if (parse.containsKey("CFBundleDisplayName")) {
            name = parse.get("CFBundleDisplayName").toString();
        }
        String version = parse.get("CFBundleShortVersionString").toString();
        String buildVersion = parse.get("CFBundleVersion").toString();
        String miniVersion = parse.get("MinimumOSVersion").toString();
        String id = parse.get("CFBundleIdentifier").toString();
        NSDictionary icons = null;
        if (parse.containsKey("CFBundleIcons")) {
            icons = (NSDictionary) parse.get("CFBundleIcons");
        }else if (parse.containsKey("CFBundleIcons~ipad")) {
            icons = (NSDictionary) parse.get("CFBundleIcons~ipad");
        }
        String iconLink = null;
        if (icons.toJavaObject()!=null) {
            List list = ((NSDictionary) icons.get("CFBundlePrimaryIcon")).get("CFBundleIconFiles").toJavaObject(List.class);
            iconLink = (String) list.get(list.size()-1);
            String iconPath = app.getAbsolutePath() + "/" + iconLink;
            File icon = new File( iconPath + "@3x.png");
            if (icon==null) {
                icon = new File(iconPath+"@2x.png");
            }
            iconLink = uploadIcon(icon);
            icon.delete();
        }
        String appLink = uploadAppFile(excelFile);
        if (appLink!=null) {
            System.out.println("ipa文件上传完成");
        }
        Package pck = packageService.getPackageByBundleIdentifier(id);
        if (pck!=null) {
            pck.setName(name);
            pck.setIcon(iconLink);
            pck.setVersion(version);
            pck.setBuildVersion(buildVersion);
            pck.setMiniVersion(miniVersion);
            pck.setLink(appLink);
            if (summary!=null) {
                pck.setSummary(summary);
            }
            int i = packageService.updatePackage(pck);
            return i;
        }
        pck = new Package();
        pck.setName(name);
        pck.setIcon(iconLink);
        pck.setVersion(version);
        pck.setBuildVersion(buildVersion);
        pck.setBundleIdentifier(id);
        pck.setMiniVersion(miniVersion);
        pck.setLink(appLink);
        pck.setSummary(summary);
        int i = packageService.insertPackage(pck);
        String mobileconfig = creatUDIDMobileconfig(pck.getId());
        if (mobileconfig!=null) {
            packageService.updateMobileconfig(mobileconfig, pck.getId());
        }else {
            i = 0;
        }
        FileUtil.del(excelFile);
        FileUtil.del(ipa);
        FileUtil.del(app);
        FileUtil.del(info);
        return i;
    }

    /**
      * create by: iizvv
      * description: 上传app
      * create time: 2019-06-28 17:21

      * @return app
      */
    String uploadAppFile(File file) {
        System.out.println("开始上传原始ipa文件");
        String objName = UUID.randomUUID().toString().replace("-", "") + ".ipa";
        fileManager.uploadFile(file, objName, false);
        return objName;
    }

    /**
     * create by: iizvv
     * description: 上传icon
     * create time: 2019-06-29 12:19

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


    /**
      * create by: iizvv
      * description: 创建获取UDID所用证书
      * create time: 2019-07-04 11:01

      * @return 证书名称
      */
    String creatUDIDMobileconfig(long id) {
        System.out.println("创建获取UDID所用证书");
        String xml = "<?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>PayloadContent</key>\n" +
                "        <dict>\n" +
                "            <key>URL</key>\n" +
                "            <string>"+ Config.udidURL +"/udid/getUDID?id="+ id +"</string> <!--接收数据的接口地址-->\n" +
                "            <key>DeviceAttributes</key>\n" +
                "            <array>\n" +
                "                <string>SERIAL</string>\n" +
                "                <string>MAC_ADDRESS_EN0</string>\n" +
                "                <string>UDID</string>\n" +
                "                <string>IMEI</string>\n" +
                "                <string>ICCID</string>\n" +
                "                <string>VERSION</string>\n" +
                "                <string>PRODUCT</string>\n" +
                "            </array>\n" +
                "        </dict>\n" +
                "        <key>PayloadOrganization</key>\n" +
                "        <string>" + Config.payloadOrganization +"</string>  <!--组织名称-->\n" +
                "        <key>PayloadDisplayName</key>\n" +
                "        <string>" + Config.payloadDisplayName + "</string>  <!--安装时显示的标题-->\n" +
                "        <key>PayloadVersion</key>\n" +
                "        <integer>1</integer>\n" +
                "        <key>PayloadUUID</key>\n" +
                "        <string>"+ UUID.randomUUID().toString().replace("-", "") +"</string>  <!--自己随机填写的唯一字符串-->\n" +
                "        <key>PayloadIdentifier</key>\n" +
                "        <string>online.iizvv.profile-service</string>\n" +
                "        <key>PayloadDescription</key>\n" +
                "        <string>"+Config.payloadDescription+"</string>   <!--描述-->\n" +
                "        <key>PayloadType</key>\n" +
                "        <string>Profile Service</string>\n" +
                "    </dict>\n" +
                "</plist>";
        String tempName = "udid_"+ id + "_" + UUID.randomUUID().toString().replace("-", "");
        String tempMobileconfig = tempName + ".mobileconfig";
        FileWriter writer = new FileWriter(tempMobileconfig);
        writer.write(xml);
        System.out.println("开始执行shell");
        String mobileconfig = tempName + "_.mobileconfig";
        String com = "/root/mobileconfig.sh " + writer.getFile().getAbsolutePath() + " " + mobileconfig;
        try {
            Shell.run(com);
            System.out.println("shell执行成功, 文件位置为: " + mobileconfig);
            File file = new File("/root/" + mobileconfig);
            mobileconfig = uploadMobileconfig(file);
            file.delete();
        } catch (Exception e) {
            System.out.println("shell执行失败");
            mobileconfig = uploadMobileconfig(writer.getFile());
            e.printStackTrace();
        }finally {
            writer.getFile().delete();
        }
        System.out.println("mobileconfig文件上传结束");
        return mobileconfig;
    }


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

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


    /**
      * create by: iizvv
      * description: 获取ipa中的app文件
      * create time: 2019-07-24 10:57

      * @return app文件
      */
    File getAppFile(File ipaFile) {
        File payload = new File(ipaFile.getAbsolutePath() + "/Payload/");
        if (payload != null) {
            for (File file : payload.listFiles()) {
                System.out.println(fileManager.getSuffixName(file));
                if (fileManager.getSuffixName(file).equalsIgnoreCase("app")) {
                    System.out.println(file.getName());
                    return file;
                }
            }
        }
        return null;
    }


}