/**
 * 数据湖presto-client模块
 * @date 2022-03
 * @author 何华东
 */

import { logger } from "mslib";
import DateUtils from "./DateUtils";
const JSONbig = require('json-bigint');
const presto = require('presto-client');

/**
 * 数据湖presto-client配置
 */
export const config = Object.assign({
    host: '112.124.209.229',
    port: '8097',
    user: 'hdfs',
    jsonParser: JSONbig
});

/**
 * 数据湖presto-client客户端实例
 */
export const prestoClient = new presto.Client(config);

/**
 * 使用presto-client从数据湖查询数据行
 * @param sql 查询sql语句
 * @param timeout 超时时间(毫秒),默认10分钟
 * @returns 
 */
export function queryRows(sql: string, timeout?: number): Promise<any[]> {
    return new Promise((resolve, reject) => {
        let response = {
            query_id: null,
            columns: null,
            data: [],
        };

        //超时取消查询任务
        let timer = setTimeout(() => {
            if (!response.query_id) return;

            prestoClient.kill(response.query_id, function (error) {
                if (error) {
                    logger.error(`数据湖查询超时,取消查询任务失败,query_id:${response.query_id}`, error);
                }
            });
        }, timeout || 1000 * 60 * 10);

        let startTime = new Date();

        prestoClient.execute({
            query: sql,
            state: function (error, query_id, stats) {
                response.query_id = query_id;
            },
            columns: function (error, data) {
                response.columns = data;
            },
            data: function (error, data, columns, stats) {
                response.data = response.data.concat(data);
            },
            success: function (error, stats, info) {
                clearTimeout(timer);

                let endTime = new Date();
                logger.info(`数据湖查询成功,query_id:${response.query_id},结束查询时间:${DateUtils.format(endTime)},耗时:${DateUtils.diffSeconds(startTime, endTime)}s,行数:${response.data?.length},sql:${sql}`);

                let rows = [];
                for (const data of response.data) {
                    let obj = {};

                    for (let j = 0; j < response.columns.length; j++) {
                        obj[response.columns[j]['name']] = data[j];
                    }

                    rows.push(obj);
                }

                resolve(rows);
            },
            error: function (error) {
                clearTimeout(timer);

                logger.error(`数据湖查询失败,query_id:${response.query_id},sql:${sql}`, error?.message);
                reject(error);
            }
        });
    });
}