//CONNECT FLUENCE
var contractInstance;

$(document).ready(function() {

    // CONNECT WEB3
    if (typeof web3 !== 'undefined') {
        // Use Mist/MetaMask's provider
        let web3js = new Web3(web3.currentProvider);
    } else {
        console.log('No web3? You should consider trying MetaMask!');
        // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
        let web3js = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    }

    //console.log(web3js);

    var controllerAddress = '0x64748b0c0b28079cf88345c1dd992d543d9f028a';
    let ControllerAbi = '[\n' +
        '\t{\n' +
        '\t\t"constant": false,\n' +
        '\t\t"inputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "id",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"name": "finzalize",\n' +
        '\t\t"outputs": [],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "nonpayable",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": true,\n' +
        '\t\t"inputs": [],\n' +
        '\t\t"name": "last5Timestamps",\n' +
        '\t\t"outputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "result",\n' +
        '\t\t\t\t"type": "uint256[5]"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "view",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": true,\n' +
        '\t\t"inputs": [],\n' +
        '\t\t"name": "verifier",\n' +
        '\t\t"outputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "",\n' +
        '\t\t\t\t"type": "address"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "view",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": true,\n' +
        '\t\t"inputs": [],\n' +
        '\t\t"name": "stake",\n' +
        '\t\t"outputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "view",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": false,\n' +
        '\t\t"inputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"components": [\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "input",\n' +
        '\t\t\t\t\t\t"type": "uint256[5]"\n' +
        '\t\t\t\t\t}\n' +
        '\t\t\t\t],\n' +
        '\t\t\t\t"name": "data",\n' +
        '\t\t\t\t"type": "tuple"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"components": [\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "a",\n' +
        '\t\t\t\t\t\t"type": "uint256[2]"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "b",\n' +
        '\t\t\t\t\t\t"type": "uint256[2][2]"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "c",\n' +
        '\t\t\t\t\t\t"type": "uint256[2]"\n' +
        '\t\t\t\t\t}\n' +
        '\t\t\t\t],\n' +
        '\t\t\t\t"name": "proof",\n' +
        '\t\t\t\t"type": "tuple"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"name": "submit",\n' +
        '\t\t"outputs": [],\n' +
        '\t\t"payable": true,\n' +
        '\t\t"stateMutability": "payable",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": true,\n' +
        '\t\t"inputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"name": "tasks",\n' +
        '\t\t"outputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"components": [\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "input",\n' +
        '\t\t\t\t\t\t"type": "uint256[5]"\n' +
        '\t\t\t\t\t}\n' +
        '\t\t\t\t],\n' +
        '\t\t\t\t"name": "data",\n' +
        '\t\t\t\t"type": "tuple"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"components": [\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "a",\n' +
        '\t\t\t\t\t\t"type": "uint256[2]"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "b",\n' +
        '\t\t\t\t\t\t"type": "uint256[2][2]"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "c",\n' +
        '\t\t\t\t\t\t"type": "uint256[2]"\n' +
        '\t\t\t\t\t}\n' +
        '\t\t\t\t],\n' +
        '\t\t\t\t"name": "proof",\n' +
        '\t\t\t\t"type": "tuple"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "submitter",\n' +
        '\t\t\t\t"type": "address"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "timestamp",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "status",\n' +
        '\t\t\t\t"type": "uint8"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "view",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": true,\n' +
        '\t\t"inputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "id",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"name": "taskDataById",\n' +
        '\t\t"outputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "data",\n' +
        '\t\t\t\t"type": "uint256[13]"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "view",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": false,\n' +
        '\t\t"inputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "id",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"name": "challenge",\n' +
        '\t\t"outputs": [],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "nonpayable",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"constant": true,\n' +
        '\t\t"inputs": [],\n' +
        '\t\t"name": "tasksNum",\n' +
        '\t\t"outputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"name": "",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"payable": false,\n' +
        '\t\t"stateMutability": "view",\n' +
        '\t\t"type": "function"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"anonymous": false,\n' +
        '\t\t"inputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"indexed": true,\n' +
        '\t\t\t\t"name": "sender",\n' +
        '\t\t\t\t"type": "address"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"indexed": false,\n' +
        '\t\t\t\t"name": "index",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"components": [\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"components": [\n' +
        '\t\t\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t\t\t"name": "input",\n' +
        '\t\t\t\t\t\t\t\t"type": "uint256[5]"\n' +
        '\t\t\t\t\t\t\t}\n' +
        '\t\t\t\t\t\t],\n' +
        '\t\t\t\t\t\t"name": "data",\n' +
        '\t\t\t\t\t\t"type": "tuple"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"components": [\n' +
        '\t\t\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t\t\t"name": "a",\n' +
        '\t\t\t\t\t\t\t\t"type": "uint256[2]"\n' +
        '\t\t\t\t\t\t\t},\n' +
        '\t\t\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t\t\t"name": "b",\n' +
        '\t\t\t\t\t\t\t\t"type": "uint256[2][2]"\n' +
        '\t\t\t\t\t\t\t},\n' +
        '\t\t\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t\t\t"name": "c",\n' +
        '\t\t\t\t\t\t\t\t"type": "uint256[2]"\n' +
        '\t\t\t\t\t\t\t}\n' +
        '\t\t\t\t\t\t],\n' +
        '\t\t\t\t\t\t"name": "proof",\n' +
        '\t\t\t\t\t\t"type": "tuple"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "submitter",\n' +
        '\t\t\t\t\t\t"type": "address"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "timestamp",\n' +
        '\t\t\t\t\t\t"type": "uint256"\n' +
        '\t\t\t\t\t},\n' +
        '\t\t\t\t\t{\n' +
        '\t\t\t\t\t\t"name": "status",\n' +
        '\t\t\t\t\t\t"type": "uint8"\n' +
        '\t\t\t\t\t}\n' +
        '\t\t\t\t],\n' +
        '\t\t\t\t"indexed": false,\n' +
        '\t\t\t\t"name": "task",\n' +
        '\t\t\t\t"type": "tuple"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"name": "Submitted",\n' +
        '\t\t"type": "event"\n' +
        '\t},\n' +
        '\t{\n' +
        '\t\t"anonymous": false,\n' +
        '\t\t"inputs": [\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"indexed": true,\n' +
        '\t\t\t\t"name": "challenger",\n' +
        '\t\t\t\t"type": "address"\n' +
        '\t\t\t},\n' +
        '\t\t\t{\n' +
        '\t\t\t\t"indexed": false,\n' +
        '\t\t\t\t"name": "index",\n' +
        '\t\t\t\t"type": "uint256"\n' +
        '\t\t\t}\n' +
        '\t\t],\n' +
        '\t\t"name": "Challenged",\n' +
        '\t\t"type": "event"\n' +
        '\t}\n' +
        ']';
    ControllerAbi = JSON.parse(ControllerAbi);
    //console.log(ControllerAbi);
    let ControllerContract = web3.eth.contract(ControllerAbi);
    //console.log(ControllerContract);
    contractInstance = ControllerContract.at(controllerAddress);
    //console.log(contractInstance);
/*
    // save fluence to global variable, so it can be accessed from Developer Console
    window.fluence = fluence;

    // convert result to a string
    window.getResultAsString = function (result) {
        return result.result().then((r) => r.asString())
    };

    window.logResultAsString = function (result) {
        return getResultAsString(result).then((r) => console.log(r))
    };
*/


    contractInstance.tasksNum(function (err, result) {
        console.log(result);
        let maxLen = Math.min(result, 5);
        for (let i = 0; i < maxLen; i++) {
            let data = result - 1 - i;
            let fluenceResponse = session.request(`{"action": "Check", "proof_id": ${data}}`);

            $('#state-id-' + i).text(result - 1 - i);
            if (fluenceResponse.hasOwnProperty('verified')) {
                if (fluenceResponse.verified) {
                    // все хорошо - мы проверили в флюенсе
                    $('challenge-' + i).prop('disabled', true);
                } else {
                    // мы проверили, пруф неправильный
                    $('#challenge-' + i).text('Challenge on Ethereum!')
                }
            }
        }
    });



    /*window.onload = function () {

        // address to Fluence contract in Ethereum blockchain. Interaction with blockchain created by MetaMask or with local Ethereum node
        let contractAddress = "0xeFF91455de6D4CF57C141bD8bF819E5f873c1A01";

        // set ethUrl to `undefined` to use MetaMask instead of Ethereum node
        let ethUrl = "http://geth.fluence.one:8545/";

        // application to interact with that stored in Fluence contract
        let appId = "218";

        // create a session between client and backend application, and then join the game
        fluence.connect(contractAddress, appId, ethUrl).then((s) => {
            console.log("Session created");
            window.session = s;
        }).then(() => join());


        // send request to list last txses

        for (let i = 0; i < 5; i++) {
            let id = document.getElementById('state-id-' + i).textContent;
            contractInstance.giveDataFromId(id, function (err, result) {

                let fluenceResponse = session.request(`{ "player_id": ${id}, "action": "GetBalance"}`);
                $('#state-status-fluence-' + i).text(fluenceResponse);
                if (fluenceResponse == true) {
                    $('challenge-' + i).prop('disabled', true);
                } else {
                    $('challenge-' + i).text('Challenge on Ethereum!')
                }
            });
        }

    };*/



});

$('button').click(function () {
    //console.log($(this)[0].id.slice(-1));
    if ($(this)[0].textContent === 'Challenge on Fluence!') {
        let id = $(this)[0].id.slice(-1);
        let data = $('#state-id-' + id)[0].textContent;
        console.log(data);
        //console.log(contractInstance);
        contractInstance.taskDataById(data, function (err, result) {
            //console.log(err);
            console.log(result);
            let public_par = result.slice(0, 5);
            let proof = result.slice(5, 13);
            let fluenceResponse = session.request(`{"action": "Verify", "proof_id": ${data}, "public_par": ${public_par}, "proof": ${proof}}`);
            console.log(fluenceResponse);
            $('#state-status-fluence-' + i).text(result);
            if (fluenceResponse.result) {
                // все хорошо - мы проверили в флюенсе
                $('challenge-' + i).prop('disabled', true);
            } else {
                // мы проверили, пруф неправильный
                $('#challenge-' + i).text('Challenge on Ethereum!')
            }
        });
    } else {
        challengeEthereum(data);
    }
});
function challengeEthereum(jobId) {
    contractInstance.challenge.sendTransaction(jobId, function (err, txHash) {
        $('challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash);
    });
}


import * as fluence from "fluence";