"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.disputes = exports.printDisputes = exports.displayDispute = exports.displayDisputes = exports.formatDispute = void 0;
const indexer_common_1 = require("@graphprotocol/indexer-common");
const graphql_tag_1 = __importDefault(require("graphql-tag"));
const yaml_1 = __importDefault(require("yaml"));
const table_1 = require("table");
const DISPUTE_FORMATTERS = {
    allocationID: x => x,
    subgraphDeploymentID: x => x,
    allocationIndexer: x => x,
    allocationAmount: x => x,
    allocationProof: x => x,
    closedEpoch: x => x,
    closedEpochReferenceProof: x => x,
    closedEpochStartBlockHash: x => x,
    closedEpochStartBlockNumber: x => x,
    previousEpochReferenceProof: x => x,
    previousEpochStartBlockHash: x => x,
    previousEpochStartBlockNumber: x => x,
    status: x => x,
};
const DISPUTES_CONVERTERS_FROM_GRAPHQL = {
    allocationID: x => x,
    subgraphDeploymentID: x => x,
    allocationIndexer: x => x,
    allocationAmount: x => +x,
    allocationProof: x => x,
    closedEpoch: x => +x,
    closedEpochReferenceProof: x => x,
    closedEpochStartBlockHash: x => x,
    closedEpochStartBlockNumber: x => +x,
    previousEpochReferenceProof: x => x,
    previousEpochStartBlockHash: x => x,
    previousEpochStartBlockNumber: x => +x,
    status: x => x,
};
/**
 * Formats a dispute for display in the console.
 */
exports.formatDispute = (rule) => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const obj = {};
    for (const [key, value] of Object.entries(rule)) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        obj[key] = DISPUTE_FORMATTERS[key](value);
    }
    return obj;
};
/**
 * Parses a POI dispute returned from the indexer management GraphQL
 * API into normalized form.
 */
const disputeFromGraphQL = (dispute) => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const obj = {};
    for (const [key, value] of Object.entries(dispute)) {
        if (key === '__typename') {
            continue;
        }
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        obj[key] = DISPUTES_CONVERTERS_FROM_GRAPHQL[key](value);
    }
    return obj;
};
exports.displayDisputes = (outputFormat, disputes) => outputFormat === 'json'
    ? JSON.stringify(disputes, null, 2)
    : outputFormat === 'yaml'
        ? yaml_1.default.stringify(disputes).trim()
        : disputes.length === 0
            ? 'No data'
            : table_1.table([Object.keys(disputes[0]), ...disputes.map(dispute => Object.values(dispute))], {
                border: table_1.getBorderCharacters('norc'),
            }).trim();
exports.displayDispute = (outputFormat, dispute) => outputFormat === 'json'
    ? JSON.stringify(dispute, null, 2)
    : outputFormat === 'yaml'
        ? yaml_1.default.stringify(dispute).trim()
        : table_1.table([Object.keys(dispute), Object.values(dispute)], {
            border: table_1.getBorderCharacters('norc'),
        }).trim();
exports.printDisputes = (print, outputFormat, disputes) => {
    if (Array.isArray(disputes)) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const formattedDisputes = disputes.map(dispute => exports.formatDispute(dispute));
        print.info(exports.displayDisputes(outputFormat, formattedDisputes));
    }
    else if (disputes) {
        const dispute = exports.formatDispute(disputes);
        print.info(exports.displayDispute(outputFormat, dispute));
    }
    else {
        print.error(`No disputes found`);
    }
};
exports.disputes = (client, status, minClosedEpoch) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const result = yield client
            .query(graphql_tag_1.default `
          query disputes($status: String!, $minClosedEpoch: Int!) {
            disputes(status: $status, minClosedEpoch: $minClosedEpoch) {
              allocationID
              allocationIndexer
              allocationAmount
              allocationProof
              closedEpoch
              closedEpochStartBlockHash
              closedEpochStartBlockNumber
              closedEpochReferenceProof
              previousEpochStartBlockHash
              previousEpochStartBlockNumber
              previousEpochReferenceProof
              status
            }
          }
        `, {
            status,
            minClosedEpoch,
        })
            .toPromise();
        if (result.error) {
            throw result.error;
        }
        return result.data.disputes.map(
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        (dispute) => {
            return disputeFromGraphQL(dispute);
        });
    }
    catch (error) {
        const err = indexer_common_1.indexerError(indexer_common_1.IndexerErrorCode.IE040, error);
        throw err;
    }
});
