<!--
    Copyright (c) 2020 Contributors to the Eclipse Foundation

    See the NOTICE file(s) distributed with this work for additional
    information regarding copyright ownership.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License 2.0 which is available at
    http://www.eclipse.org/legal/epl-2.0

    SPDX-License-Identifier: EPL-2.0
 -->
<template xmlns:v-contextmenu="http://www.w3.org/1999/xhtml">
  <div style="height: 100%; position: relative">
    <v-contextmenu ref="contextmenu">
      <v-contextmenu-submenu :title="$t('jifa.heap.ref.object.label')">
        <v-contextmenu-item
                @click="$emit('outgoingRefsOfObj', contextMenuTargetObjectId, contextMenuTargetObjectLabel)">
          {{$t('jifa.heap.ref.object.outgoing')}}
        </v-contextmenu-item>
        <v-contextmenu-item
                @click="$emit('incomingRefsOfObj', contextMenuTargetObjectId, contextMenuTargetObjectLabel)">
          {{$t('jifa.heap.ref.object.incoming')}}
        </v-contextmenu-item>
      </v-contextmenu-submenu>
      <v-contextmenu-submenu :title="$t('jifa.heap.ref.type.label')">
        <v-contextmenu-item
                @click="$emit('outgoingRefsOfClass', contextMenuTargetObjectId, contextMenuTargetObjectLabel)">
          {{$t('jifa.heap.ref.type.outgoing')}}
        </v-contextmenu-item>
        <v-contextmenu-item
                @click="$emit('incomingRefsOfClass', contextMenuTargetObjectId, contextMenuTargetObjectLabel)">
          {{$t('jifa.heap.ref.type.incoming')}}
        </v-contextmenu-item>
      </v-contextmenu-submenu>
      <v-contextmenu-item divider></v-contextmenu-item>
      <v-contextmenu-item
              @click="$emit('pathToGCRootsOfObj', contextMenuTargetObjectId, contextMenuTargetObjectLabel)">
        {{$t('jifa.heap.pathToGCRoots')}}
      </v-contextmenu-item>
    </v-contextmenu>

    <div style="height: 45px; margin-top: 5px">
      <el-autocomplete
              v-model="oql"
              :fetch-suggestions="queryHistory"
              placeholder="Object Query Language ..."
              :trigger-on-focus="false"
              prefix-icon="el-icon-edit"
              @keyup.enter.native="search"
              clearable
              style="display: flex"
      >
        <template slot="append">
          <el-button :icon="searching ? 'el-icon-loading':'el-icon-search'" :disabled="searching" @click="search">
          </el-button>
        </template>
      </el-autocomplete>
    </div>

    <div align="left" style="height: 25px; margin-bottom: 5px">
      <a href="https://help.eclipse.org/oxygen/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Freference%2Foqlsyntax.html&cp=66_4_2"
         target="_blank" style="font-size: 12px; font-weight: bold; color: #909399">
        OQL Help
      </a>
    </div>

    <div v-loading="loading" style="position: absolute; top: 80px; left: 0; right: 0; bottom: 0;">
      <el-table v-if="isTreeResult"
                ref='treeResultTable' :data="treeTableData"
                :highlight-current-row="false"
                stripe
                :header-cell-style="headerCellStyle"
                :cell-style='cellStyle'
                row-key="rowKey"
                lazy
                :indent=8
                height="100%"
                :load="loadOutbounds">
        <el-table-column label="Class Name" width="800px" show-overflow-tooltip>
          <template slot-scope="scope">
            <span v-if="scope.row.isResult" @click="$emit('setSelectedObjectId', scope.row.objectId)"
                  style="cursor: pointer"
                  @contextmenu="contextMenuTargetObjectId = scope.row.objectId; contextMenuTargetObjectLabel = scope.row.label"
                  v-contextmenu:contextmenu>
              <img :src="scope.row.icon" style="margin-right: 5px"/>
              <strong>{{ scope.row.prefix }}</strong>
              {{ scope.row.label }}
              <span style="font-weight: bold; color: #909399">
                {{ scope.row.suffix }}
              </span>
            </span>

            <span v-if="scope.row.isOutboundsSummary">
              <img :src="ICONS.misc.sumIcon" v-if="scope.row.currentSize >= scope.row.totalSize"/>
              <img :src="ICONS.misc.sumPlusIcon"
                   @dblclick="fetchOutbounds(scope.row.parentRowKey, scope.row.objectId, scope.row.nextPage, scope.row.resolve)"
                   style="cursor: pointer"
                   v-else/>
              {{ scope.row.currentSize }} <strong> / </strong> {{ scope.row.totalSize }}
            </span>

            <span v-if="scope.row.isSummaryItem">
              <img :src="ICONS.misc.sumIcon" v-if="treeResult.length >= totalSize"/>
              <img :src="ICONS.misc.sumPlusIcon" @dblclick="fetchResult(scope.row.oql)" style="cursor: pointer" v-else/>
              {{ treeResult.length }} <strong> / </strong> {{totalSize}}
            </span>
          </template>
        </el-table-column>
        <el-table-column label="Shallow Heap" prop="shallowHeap">
        </el-table-column>
        <el-table-column label="Retained Heap" prop="retainedHeap">
        </el-table-column>
      </el-table>

      <el-table v-if="isTableResult"
                ref='tableResultTable' :data="tableTableData"
                :highlight-current-row="false"
                stripe
                :header-cell-style="headerCellStyle"
                :cell-style='cellStyle'
                row-key="rowKey"
                lazy
                :indent=8
                height="100%">

        <el-table-column v-for="(column, index) in tableResultColumns" :label="column" v-bind:key="column">
          <template slot-scope="scope">
          <span v-if="scope.row.isResult" @click="$emit('setSelectedObjectId', scope.row.objectId)"
                style="cursor: pointer"
                @contextmenu="contextMenuTargetObjectId = scope.row.objectId; contextMenuTargetObjectLabel = scope.row.values[index] ? scope.row.values[index] : 'null'"
                v-contextmenu:contextmenu>
            {{ scope.row.values[index] ? scope.row.values[index] : 'null' }}
          </span>

            <span v-if="scope.row.isSummaryItem && index === 0">
            <img :src="ICONS.misc.sumIcon" v-if="tableResult.length >= totalSize"/>
            <img :src="ICONS.misc.sumPlusIcon" @dblclick="fetchResult(scope.row.oql)" style="cursor: pointer" v-else/>
            {{ tableResult.length }} <strong> / </strong> {{totalSize}}
          </span>
          </template>
        </el-table-column>
      </el-table>


      <el-input v-if="isTextResult"
                v-model="textResult"
                type="textarea"
                readonly
                autosize>
      </el-input>
    </div>
  </div>
</template>

<script>
  import axios from 'axios'
  import {getOutboundIcon, ICONS} from "./IconHealper";
  import {heapDumpService} from "../../util";

  let rowKey = 1

  // oql result type
  const TREE = 1
  const TABLE = 2
  const TEXT = 3

  export default {
    props: ['file'],
    data() {
      return {
        ICONS,
        cellStyle: {padding: '4px', fontSize: '12px'},
        headerCellStyle: {padding: 0, 'font-size': '12px', 'font-weight': 'normal'},
        searching: false,
        loading: false,
        oql: '',
        nextPage: 1,
        pageSize: 25,
        totalSize: 0,
        resultType: 0,

        contextMenuTargetObjectId: null,
        contextMenuTargetObjectLabel: null,

        treeResult: [],
        treeTableData: [],

        tableResult: [],
        tableResultColumns: [],
        tableTableData: [],

        textResult: '',

        isTreeResult: false,
        isTableResult: false,
        isTextResult: false,

        historyOQLs: []
      }
    },
    methods: {
      adjustDataByResultType(type) {
        this.isTreeResult = type === TREE
        this.isTableResult = type === TABLE
        this.isTextResult = type === TEXT
      },
      fetchResult(oql) {
        if (!oql || oql.length === 0) {
          return
        }
        this.loading = true
        axios.get(heapDumpService(this.file, 'oql'), {
          params: {
            oql: oql,
            page: this.nextPage,
            pageSize: this.pageSize,
          }
        }).then(resp => {
          this.adjustDataByResultType(resp.data.type)
          if (this.isTreeResult) {
            this.putHistory(oql)
            this.totalSize = resp.data.pv.totalSize
            let data = resp.data.pv.data
            data.forEach(d => {
              this.treeResult.push({
                rowKey: rowKey++,
                icon: getOutboundIcon(d.gCRoot, d.objectType),
                prefix: d.prefix,
                label: d.label,
                suffix: d.suffix,
                shallowHeap: d.shallowSize,
                retainedHeap: d.retainedSize,
                hasChildren: d.hasOutbound,
                objectId: d.objectId,
                isResult: true
              })
            })
            this.treeTableData = this.treeResult.concat({
              rowKey: rowKey++,
              oql: oql,
              isSummaryItem: true
            })
            this.nextPage++
          } else if (this.isTableResult) {
            this.putHistory(oql)
            this.totalSize = resp.data.pv.totalSize
            this.tableResultColumns = resp.data.columns
            let data = resp.data.pv.data
            data.forEach(d => {
              this.tableResult.push({
                rowKey: rowKey++,
                objectId: d.objectId,
                values: d.values,
                hasChildren: false,
                isResult: true
              })
            })
            this.tableTableData = this.tableResult.concat({
              rowKey: rowKey++,
              oql: oql,
              isSummaryItem: true
            })
            this.nextPage++
          } else if (this.isTextResult) {
            this.textResult = resp.data.text
          }
          this.searching = false
          this.loading = false
        })
      },
      loadOutbounds(tree, treeNode, resolve) {
        this.fetchOutbounds(tree.rowKey, tree.objectId, 1, resolve)
      },
      fetchOutbounds(parentRowKey, objectId, page, resolve) {
        this.loading = true
        axios.get(heapDumpService(this.file, 'outbounds'), {
          params: {
            objectId: objectId,
            page: page,
            pageSize: this.pageSize,
          }
        }).then(resp => {
          let loadedLen = 0;
          let loaded = this.$refs['treeResultTable'].store.states.lazyTreeNodeMap[parentRowKey]
          let callResolve = false
          if (loaded) {
            loadedLen = loaded.length
            if (loadedLen > 0) {
              loaded.splice(--loadedLen, 1)
            }
          } else {
            loaded = []
            callResolve = true;
          }

          let res = resp.data.data
          res.forEach(d => {
            loaded.push({
              rowKey: rowKey++,
              icon: getOutboundIcon(d.gCRoot, d.objectType),
              prefix: d.prefix,
              label: d.label,
              suffix: d.suffix,
              shallowHeap: d.shallowSize,
              retainedHeap: d.retainedSize,
              hasChildren: d.hasOutbound,
              objectId: d.objectId,
              isResult: true
            })
          })

          loaded.push({
            rowKey: rowKey++,
            objectId: objectId,
            parentRowKey: parentRowKey,
            isOutboundsSummary: true,
            nextPage: page + 1,
            currentSize: loadedLen + res.length,
            totalSize: resp.data.totalSize,
            resolve: resolve,
          })

          if (callResolve) {
            resolve(loaded)
          }
          this.loading = false
        })
      },
      clear() {
        this.nextPage = 1
        this.totalSize = 0

        this.treeResult = []
        this.treeTableData = []

        this.tableResult = []
        this.tableResultColumns = []
        this.tableTableData = []
        this.textResult = ''
      },

      search() {
        if (this.oql) {
          this.searching = true
          this.clear()
          this.fetchResult(this.oql)
        }
      },

      putHistory(oql) {
        let target = oql.trim()
        for (let i = 0; i < this.historyOQLs.length; i++) {
          if (this.historyOQLs[i].value === target) {
            return
          }
        }

        this.historyOQLs.push({value: target})
        if (this.historyOQLs.length > 11) {
          this.historyOQLs.shift()
        }
      },

      queryHistory(queryString, cb) {
        let history = this.historyOQLs;
        let results = queryString ? history.filter(this.createFilter(queryString)) : history;
        cb(results);
      },

      createFilter(queryString) {
        return (history) => {
          return (history.value.toLowerCase().indexOf(queryString.toLowerCase().trim()) === 0);
        };
      },
    }
  }
</script>
