function expandOrCollapse() {
    const outputNavEl = $("#outputNav")
    if (outputNavEl.hasClass("col-2")) {
        outputNavEl.removeClass("col-2").addClass("col-6");
        $("#mainBox").removeClass("col-8").addClass("col-4");
        $("#expand").html("收起");
    } else {
        outputNavEl.removeClass("col-6").addClass("col-2");
        $("#mainBox").removeClass("col-4").addClass("col-8");
        $("#expand").html("展开");
    }
}

function listContracts() {
    global.wssocket.send(JSON.stringify({
        action: 'listContractProcess',
        filters: 2
    }));
}

function startContract() {
    const key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
    const sm2Key = JSON.parse(key.sm2Key);
    const projectId = $("#selectedProject")[0].value;
    const project = global.projects[projectId];
    startResult.innerText = "正在启动合约:" + project;

    const request = {};
    request.action = "startContract";
    request.isPrivate = $("#privateprojecttab").hasClass("active");

    request.owner = sm2Key.publicKey;
    request.requestID = new Date().getTime() + "";
    // request.contractid = $("#tabdiv")[0].value;
    // request.script = global.scriptEditor.getValue();
    request.path = "/" + project + "/mainfest.json";
    localStorage.setItem("persisStatus", JSON.stringify(request));
    {
        request.signature = sm2.doSignature("Fixed|" + request.path + "|"
            + sm2Key.publicKey, sm2Key.privateKey);
        request.script = "empty";
    }
    global.wssocket.send(JSON.stringify(request));
}

function startContractAsDebug() {
    const key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
    const sm2Key = JSON.parse(key.sm2Key);
    const projectId = $("#selectedProject")[0].value;
    const project = global.projects[projectId];
    startResult.innerText = "正在以调试模式启动合约:" + project;

    const request = {};
    request.action = "startContractAsDebug";
    request.isPrivate = $("#privateprojecttab").hasClass("active");

    request.owner = sm2Key.publicKey;
    request.requestID = new Date().getTime() + "";
    // request.contractid = $("#tabdiv")[0].value;
    // request.script = global.scriptEditor.getValue();
    request.path = "/" + project + "/mainfest.json";
    localStorage.setItem("persisStatus", JSON.stringify(request));
    {
        request.signature = sm2.doSignature("Fixed|" + request.path + "|"
            + sm2Key.publicKey, sm2Key.privateKey);
        request.script = "empty";
    }
    global.wssocket.send(JSON.stringify(request));
}

function stopContract() {
    global.wssocket.send(JSON.stringify({
        action: 'killContractProcess',
        requestID: new Date().getTime().toString(),
        name: mainVue.contracts[selectedContract.value].name,
        id: mainVue.contracts[selectedContract.value].id
    }));
}

function genReadme() {
    const request = {
        isPrivate: global.currentFile.isPrivate,
        path: global.currentFile.path
    };
    const tmpIndex = request.path.lastIndexOf('/');
    const yjsName = request.path.substring(tmpIndex + 1, request.path.length - 4);
    request.path = request.path.substring(0, tmpIndex);
    const key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
    const sm2Key = JSON.parse(key.sm2Key);

    for (const c of mainVue.contracts) {
        //  这里假设合约名同文件名
        if (yjsName === c.name) {
            const exportedFunction = c.exportedFunctions;
            ReadmeFunction = [];
            for (let f of exportedFunction) {
                let description = "暂无描述";
                let readmeFunc = {};
                readmeFunc.functionName = f.functionName;
                readmeFunc.description = description;
                for (let anno of f.annotations) {
                    if (anno.type === 'Param') {
                        readmeFunc.args = anno.args[0];
                    } else if (anno.type === 'Description') {
                        readmeFunc.description = anno.args[0];
                    } else if (anno.type === 'Result') {
                        readmeFunc.result = anno.args[0];
                    }
                }
                ReadmeFunction.push(readmeFunc);
            }
            request.action = "generateReadme";

            request.contractID = c.id;
            request.contractName = c.name;
            request.pubkey = sm2Key.publicKey;
            global.wssocket.send(JSON.stringify(request));
            return;
        }
    }
    myToast("生成文档失败", "请启动合约并检查合约与文件名是否一致！");
}

function genData() {
    const key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
    const sm2Key = JSON.parse(key.sm2Key);
    const value = selectedContract.value;
    if (value && value !== "选择合约实例") {
        const request = {};
        request.action = "generateDataFromRM";
        request.requestID = `${new Date().getTime()}_${Math.floor(Math.random() * 10000)}`;
        const contract = mainVue.contracts[selectedContract.value];
        request.isPrivate = $("#privateprojecttab").hasClass("active");
        request.contractID = contract.id;
        request.contractName = mainVue.contracts[selectedContract.value].name;
        request.pubkey = sm2Key.publicKey;
        request.signature = sm2.doSignature(
            `${request.contractID}|${arg.action}|${arg.arg}|${sm2Key.publicKey}`,
            sm2Key.privateKey,
            {hash: true, der: true});
        const gasLimit = $('#gasLimit').val()
        request.arg = JSON.stringify({
            gasLimit: gasLimit ? gasLimit : '1000'
        });
        localStorage.setItem("persisArg", JSON.stringify(request));
        global.wssocket.send(JSON.stringify(request));
    }
}

function queryContractInstanceDOI() {
    global.wssocket.send(JSON.stringify({
        action: "queryContractInstanceDOI",
        requestID: new Date().getTime().toString(),
        name: mainVue.contracts[selectedContract.value].name,
        id: mainVue.contracts[selectedContract.value].id
    }));
}

function queryContractInstanceInfoByDOI() {
    global.wssocket.send(JSON.stringify({
        action: 'queryContractInstanceInfoByDOI',
        requestID: new Date().getTime().toString(),
        doi: contractInstanceDOIInput.value
    }));
}

function importContractInstanceCodeByDOI() {
    global.wssocket.send(JSON.stringify({
        action: "importContractInstanceCodeByDOI",
        requestID: new Date().getTime().toString(),
        doi: contractInstanceDOIInput.value
    }));
}

function openInClient() {
    window.open(isBaaS ?
        `${location.origin}/client/BaaSClient.html${location.search}` :
        `${location.origin}/client/bdwareclient.html?self=true&` +
        `contract=${mainVue.contracts[selectedContract.value].id}`);
}

function stopAllContract() {
    global.wssocket.send(JSON.stringify({
        action: 'killAllContract'
    }));
}

function selectContractToExecute() {
    const value = selectedContractAtExecute.value;
    if (value && value !== "选择实例" && mainVue.contracts[value]) {
        mainVue.contractFunctions = mainVue.contracts[value].exportedFunctions;

        global.wssocket.send(JSON.stringify({
            action: "connectTo",
            name: mainVue.contracts[value].name,
            id: mainVue.contracts[value].id
        }));
    }
}

function executeContract() {
    if (!selectedFunction.value) {
        myToast("调用合约失败", "请选择合约方法");
        return;
    }
    if (!selectedContractAtExecute.value) {
        myToast("调用合约失败", "请选择合约");
        return;
    }
    const key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
    const sm2Key = JSON.parse(key.sm2Key);
    const request = {};
    request.action = "executeContract";
    request.requestID = new Date().getTime() + "_"
        + Math.floor(Math.random() * 10000);
    const contract = mainVue.contracts[selectedContractAtExecute.value];

    request.contractID = contract.id;
    request.operation = contract.exportedFunctions[selectedFunction.value].functionName;
    const arg = executeContractArgInput.value;
    const gasLimit = $('#gasLimit').val()/1;
    request.pubkey = sm2Key.publicKey;
    var toSign = request.contractID + "|"
                    + request.operation + "|" + arg ;
    if (gasLimit>0){
      request.gasLimit = gasLimit;
      toSign+= "|" + gasLimit;
    }
    toSign+= "|" + sm2Key.publicKey;
    request.signature = sm2.doSignature(
        toSign,
        sm2Key.privateKey,
        {hash: true, der: true});
    request.arg = arg;
    localStorage.setItem("persisArg", JSON.stringify(request));
    global.wssocket.send(JSON.stringify(request));
}

function executeContractWithDynamicResult() {
    if (!selectedFunction.value) {
        myToast("调用合约失败", "请选择合约方法");
        return;
    }
    if (!selectedContractAtExecute.value) {
        myToast("调用合约失败", "请选择合约");
        return;
    }
    console.log("executeContractWithDynamicResult");
    const request = {};
    request.action = "executeContract";
    request.requestID = new Date().getTime() + "";

    const contract = mainVue.contracts[selectedContractAtExecute.value];
    request.contractName = contract.id;

    const arg = {
        action: contract.exportedFunctions[selectedFunction.value].functionName,
        arg: executeContractArgInput.value
    };

    request.withDyanmicAnalysis = true;
    request.arg = "{\"action\":\"" + arg.action + "\",\"arg\":\"" + arg.arg
        + "\"}";
    request.pubkey = global.sm2Key.publicKey;
    request.signature = sm2.doSignature(
        `${request.contractID}|${arg.action}|${arg.arg}|${global.sm2Key.publicKey}`,
        global.sm2Key.privateKey,
        {hash: true, der: true});
    localStorage.setItem("persisArg", JSON.stringify(request));
    global.wssocket.send(JSON.stringify(request));
}

function testEvaluates() {
    if (!selectedFunction.value) {
        myToast("调用合约失败", "请选择合约方法");
        return;
    }
    if (!selectedContractAtExecute.value) {
        myToast("调用合约失败", "请选择合约");
        return;
    }
    console.log("Evaluates");
    const contract = mainVue.contracts[selectedContractAtExecute.value];

    global.wssocket.send(JSON.stringify({
        action: "evaluates",
        contractName: contract.id,
        functionName: contract.exportedFunctions[selectedFunction.value].functionName,
        args: executeContractArgInput.value
    }));
}

