<template>
  <div class="oo-page">
    <Spin size="large" v-if="isLoading">正在获取执行结果...</Spin>
    <div class="oo-server" :loading="isLoading">
      <p>命令内容：{{command}}</p>
      <cs-dynamic-table ref="child" :prop="csTable" :parent="this"></cs-dynamic-table>
      <div v-if="false" class="result-panel-bottom">
        <p>
          <span>【{{host}}】的执行结果</span>
          <span v-on:click="showResultPanel=!showResultPanel">{{showResultPanel?"折叠":"展开"}}</span>
        </p>
        <Divider />
        <pre class="result-panel-pre">{{tailStdout}}</pre>
      </div>

      <Drawer
        :closable="true"
        :width="width"
        :mask="false"
        :styles="{backgroundColor:'black'}"
        v-model="showResultPanel"
      >
        <div class="result-panel">
          <p>
            <span>【{{host}}】的执行结果</span>
            <a title="结果窗口宽度" @click="width=45">45%</a>
            <a @click="width=60">60%</a>
            <a @click="width=80">80%</a>
            <a @click="width=100">100%</a>
          </p>
          <Divider />
          <pre class="result-panel-pre">{{tailStdout}}</pre>
        </div>
      </Drawer>
    </div>
    <Row class="buttonDiv">
      <Button @click="exportResult" type="primary" style="margin-right:5px">导&nbsp;&nbsp;出</Button>
      <Button @click="cancel">关&nbsp;&nbsp;闭</Button>
    </Row>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Emit, Prop } from "vue-property-decorator";
import XLSX from "xlsx";
import FileSaver from "file-saver";
@Component
export default class CmdRunResult extends Vue {
  private tailStdout: any = "";
  private host: any = "";
  private command: any = "";
  private showResultPanel: boolean = false;
  private timer: any = null;
  private isLoading: boolean = true;
  private width: any = 45;
  private csTable: any = {
    formWidth: 35,
    parentVm: this,
    dataSrc: this.$msPrefix.automation + "/api/v1/data/list/job",
    delSrc: this.$msPrefix.automation + "/api/v1/data/delete/job/",
    batchDelUri: this.$msPrefix.automation + "/api/v1/data/batch/job",
    paginationByFront: true,
    dataPropFront: "data",
    dataProp: "data.content",
    postMethod: true,
    dataFun: this.mockTableFun,
    pageableProp: {
      pageSize: "data.size",
      total: "data.totalElements",
      currentPage: "data.number"
    },
    showIndex: true,
    emptyModel: {},
    actions: {
      //表头操作按钮
      replace: true,
      def: []
    },
    columns: [
      // {
      //   key: "command",
      //   title: "命令内容",
      //   ellipsis: true,
      //   align: "center"
      // },
      {
        key: "host",
        title: "服务器名",
        align: "left",
        tooltip: true
      },
      {
        key: "tailStdout",
        title: "标准输出",
        align: "left",
        ellipsis: true,
        tooltip: true,
        minWidth: 80,
        render: (h, params) => {
          let tip = params.row.tailStdout;
          if (tip && tip.length >= 30) {
            tip = tip.substring(0, 27) + "...";
          }
          //let e=this.clickEvent;
          // return h("Poptip",{
          //         props:{
          //             trigger:"hover",
          //             transfer:true,
          //             placement:"top"
          //         },
          //         scopedSlots:{
          //             content: props=>h("pre",params.row.tailStdout)
          //         }
          //     },[
          //         h("span",tip),
          //     ]
          // );
          return h(
            "a",
            {
              props: {
                type: "text"
              },
              on: {
                click: () => this.showTailStdout(params)
              }
            },
            tip
          );
        }
      },
      {
        key: "errorCode",
        title: "错误信息",
        align: "center",
        ellipsis: true,
        tooltip: true
      }
    ]
  };
  showTailStdout(params) {
    this.showResultPanel = true;
    this.tailStdout = params.row.tailStdout;
    this.host = params.row.host;
  }
  mockTableFun() {}

  postTableData(id, command, flag = false) {
    clearInterval(this.timer);
    this.command = command;
    var setTimeJob = () => {
      if (!flag) {
        this.getJobResult(id, command);
      } else {
        this.findJob(id, command);
      }
      return setTimeJob;
    };
    console.info("try to get command result");
    this.timer = setInterval(setTimeJob(), 2000);
  }

  getJobResult(id, command) {
    this.isLoading = true;
    this.getApiData(
      "get",
      this.$msPrefix.automation + "/api/v1/job/findJobResult?jobId=" + id,
      {},
      res => {
        var str = res.data.result;
        this.processResult(str, command);
      },
      err => {
        this.$tools.message("error", "获取执行结果失败！");
        this.isLoading = false;
      }
    );
  }

  findJob(id, command) {
    this.isLoading = true;
    this.getApiData(
      "post",
      this.$msPrefix.automation + "/api/v1/data/list/job",
      { id: ["" + id] },
      res => {
        var str = res.data.content[0].result;
        this.processResult(str, command);
      },
      err => {
        this.$tools.message("error", "获取执行结果失败！");
        this.isLoading = false;
      }
    );
  }

  processResult(resStr, command) {
    let tableData: Array<any> = [];
    if (resStr) {
      let data = JSON.parse(resStr);
      data.elemResultInfo.forEach(item => {
        tableData.push(this.createResultItem(item, command));
      });
      console.info("tableData", tableData);
      this.csTable.paginationByFront = true;
      this.csTable.dataFun = this.mockTableFun;
      let childVue = this.$refs.child as any;
      if (childVue) {
        childVue.afterGetData({ data: tableData });
      }
      this.isLoading = false;
      this.clearTime();
    }
  }

  createResultItem(item, command) {

    if (!item.output) {
      item.output = {};
    }
    item.output.command = command;
    item.output.host = item.element.name;
    console.info("item", item);
    console.log("error", item.error);
    if (!item.error) {
      item.error = { legacyErrorCode: "" };
    }
    item.output.errorCode = item.error.legacyErrorCode;

    if (!item.output.tailStdout) {
      item.output.tailStdout = "";
    }
    if (!item.output.tailStderr) {
      item.output.tailStderr = "";
    }
    let output = item.output.tailStdout + item.output.tailStderr + "";
    item.output.tailStdout = output;
    delete item.output.tailStderr;
    return item.output;
  }

  exportResult() {
    const titles = {
      command: "命令内容",
      host: "主机名",
      tailStdout: "标准输出",
      errorCode: "错误信息",
      exitCode: "退出码"
    };
    const fields = ["command", "host", "tailStdout", "errorCode", "exitCode"];

    let data = (this.$refs.child as any).tableData;
    let sheet0 = this.createWs(data, fields, titles);
    let wopts: any = { bookType: "xlsx", bookSST: false, type: "array" };
    let wb = { SheetNames: ["Sheet0"], Sheets: {}, Props: {} };
    wb.Sheets["Sheet0"] = sheet0; //转化成workbooks形式。
    let wbout = XLSX.write(wb, wopts);
    try {
      FileSaver.saveAs(
        new Blob([wbout], { type: "application/octet-stream" }),
        "命令执行结果.xlsx"
      );
    } catch (e) {
      if (typeof console !== "undefined") console.log(e, wbout);
    }
    return wbout;
  }

  createWs(data, fields, titles) {
    const ws: any = XLSX.utils.json_to_sheet(data, {
      header: fields
    });
    const range = XLSX.utils.decode_range(ws["!ref"]);

    for (let c = range.s.c; c <= range.e.c; c++) {
      const header = XLSX.utils.encode_col(c) + "1";
      ws[header].v = titles[ws[header].v];
    }

    return ws;
  }

  clearTime() {
    clearInterval(this.timer);
  }

  @Emit("closeModal") close() {}
  cancel() {
    this.showResultPanel = false;
    clearInterval(this.timer);
    this.close();
  }
}
</script>
<style>
.result-panel-bottom {
  max-height: 200px;
  overflow: auto;
  background-color: black;
  color: white;
  margin-bottom: 10px;
}

.result-panel-pre {
  max-height: 100%;
  overflow: auto;
  background-color: black;
  color: white;
  margin-bottom: 10px;
}
.result-panel > p > span,
.result-panel > p > a {
  margin-right: 20px;
  color: white;
}
.ivu-drawer-mask,
.ivu-drawer-wrap {
  z-index: 2000;
}
</style>
