<template>
<div>
    <div class="q-gutter-md q-mb-sm q-pa-lg">
        <q-card class="bg-transparent no-shadow no-border">
            <q-card-section class="q-pa-none">
                <div class="row q-col-gutter-sm">
                    <div v-for="(item, index) in Threatitems" :key="index" class="col-md-3 col-sm-12 col-xs-12">
                        <q-item :style="`background-color: ${item.color1}`" class="q-pa-none">
                            <q-item-section side :style="`background-color: ${item.color2}`" class="q-pa-lg q-mr-none text-white">
                                <q-icon :name="item.icon" color="white" size="24px"></q-icon>
                            </q-item-section>
                            <q-item-section class="q-pa-md q-ml-none text-white">
                                <q-item-label class="text-white text-h6 text-weight-bolder">{{
                  item.value
                }}</q-item-label>
                                <q-item-label>{{ item.title }}</q-item-label>
                            </q-item-section>
                        </q-item>
                    </div>
                </div>
            </q-card-section>
        </q-card>
    </div>
    <div class="row">
        <div class="col"></div>
        <div class="col">
            <div class="row q-gutter-md q-mb-sm q-pa-lg">
                <q-timeline layout="dense" side="right" color="red">
                    <template v-if="!server_threat.data || server_threat.data.length == 0">
                        <h4>暂无可用数据,下次刷新时间 {{last_refresh}}...</h4>
                    </template>
                    <template v-for="(threat, index) in server_threat.data" :key="index">
                        <q-timeline-entry :subtitle="'主机:' + threat.host" side="left">
                            <div>
                                <q-card flat bordered style="overflow: auto" :thumb-style="thumbStyle" :bar-style="barStyle">
                                    <q-card-section horizontal>
                                        <div class="bg-red-5">&nbsp;</div>
                                        <q-card-actions vertical class="justify-around q-px-md">
                                            <div>进程链hash: {{ threat.chain_hash }}</div>
                                            <div>进程: {{ threat.start_process.path }}</div>
                                            <div>用户: {{ threat.start_process.user }}</div>
                                            <div>
                                                分数:
                                                <q-chip square color="orange" text-color="white" icon-right="visibility">
                                                    {{ threat.risk_score }}
                                                </q-chip>
                                            </div>
                                            <div>
                                                活动状态:
                                                <q-chip square :color="threat.is_end == 1 ? 'negative' : 'red'" text-color="white">
                                                    {{ threat.is_end == 1 ? "已结束" : "进行中" }}
                                                </q-chip>
                                            </div>
                                            <div>
                                                产生的威胁:
                                                <template v-for="(index, operation) in threat.hit_rule" :key="index">
                                                    <q-chip square color="rgb(239,243,246)">
                                                        {{ operation }}&nbsp;({{ index }})
                                                    </q-chip>
                                                </template>
                                            </div>
                                            <div>
                                                <q-btn flat color="accent" @click="show_details(threat.id)" icon="open_in_new">
                                                    查看详情
                                                </q-btn>
                                                <q-btn flat color="accent" @click="search_vt(threat.start_process.hash)" icon="search">
                                                    在VT上搜索
                                                </q-btn>
                                                <q-btn flat color="accent" @click="handle_threat(threat.id, 1)" icon="done">
                                                    确认威胁
                                                </q-btn>
                                                <q-btn flat color="accent" @click="handle_threat(threat.id, 2)" icon="texture">
                                                    忽略威胁
                                                </q-btn>
                                                <q-btn flat color="accent" icon="close" @click="delete_threat(threat.id)">
                                                    删除报警
                                                </q-btn>
                                            </div>
                                        </q-card-actions>
                                    </q-card-section>
                                </q-card>
                            </div>
                        </q-timeline-entry>
                    </template>
                </q-timeline>
            </div>
        </div>
        <div class="col"></div>
    </div>
</div>
<q-dialog v-model="addwhiteListHash" persistent transition-show="scale" transition-hide="scale">
    <q-card style="min-width: 350px">
        <q-card-section>
            <div class="text-h6">填写缘由</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
            <q-input dense v-model="this.whiteListPostData.reason" autofocus />
        </q-card-section>

        <q-card-actions align="right" class="text-primary">
            <q-btn flat label="取消" @click="addwhiteListHash = false" v-close-popup />
            <q-btn flat label="加入白名单" v-close-popup @click="add_to_white_hash_post()" />
        </q-card-actions>
    </q-card>
</q-dialog>
<q-dialog v-model="dialog" persistent :maximized="maximizedToggle" transition-show="slide-up" transition-hide="slide-down">
    <q-card class="text-white">
        <q-bar>
            <q-space></q-space>
            <q-btn dense flat icon="close" v-close-popup>
                <q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
            </q-btn>
        </q-bar>
        <div class="row" style="width: 100%; height: 100%">
            <div ref="main_draw" style="width: 100%; height: 100%; margin-left: 5%">
                1
            </div>
        </div>
        <q-drawer show-if-above v-if="processChainShowDetails" v-model="processChainShowDetails" side="right" bordered width="350" class="text-dark">
            <q-list style="width: 100%;word-break: break-all;">
               <q-item>
                    <q-item-section>活跃状态: {{processChainDetails.active ? "运行中" : "已结束"}}</q-item-section>
                </q-item>
                <q-separator />
                <q-item>
                    <q-item-section>进程名字: {{processChainDetails.name}}</q-item-section>
                </q-item>
                <q-separator />
                <q-item>
                    <q-item-section>进程路径: {{processChainDetails.path}}</q-item-section>
                </q-item>
                <q-separator />
                <q-item>
                    <q-item-section>进程参数: {{processChainDetails.params}}</q-item-section>
                </q-item>
                <q-separator />
                <q-item>
                    <q-item-section>进程id: {{processChainDetails.pid}}</q-item-section>
                </q-item>
                <q-separator />
                <q-item>
                    <q-item-section>父进程id: {{processChainDetails.ppid}}</q-item-section>
                </q-item>
                <q-separator />
                <q-item>
                    <q-item-section>进程hash: {{processChainDetails.md5}}</q-item-section>
                </q-item>
                <q-separator />
                 <q-item>
                    <q-item-section>是否在白名单中: {{processChainDetails.isWhite ? "是" : "否"}}</q-item-section>
                </q-item>
                <q-separator />
                <q-item>
                    <q-item-section>进程命中的规则: <template v-for="(index, operation) in processChainDetails.hitRules" :key="index">
                            <q-chip square color="rgb(239,243,246)">
                                {{ operation }}&nbsp;({{ index }})
                            </q-chip>
                        </template></q-item-section>
                </q-item>
                <q-item>
                    <q-btn icon="search" outline style="color: grey;width: 100%;" label="搜索hash" @click="search_vt(processChainDetails.md5)" />
                </q-item>
                <q-item>
                    <template v-if="processChainDetails.isWhite == false">
                        <q-btn icon="texture" outline style="color: grey;width: 100%;" label="加入白名单" @click="add_to_white_hash_pre(processChainDetails.path,processChainDetails.md5)" />
                    </template>
                    <template v-else>
                        <q-btn icon="clear" outline style="color: grey;width: 100%;" label="从白名单中删除" @click="delete_white_hash(processChainDetails.md5)" />
                    </template>
                </q-item>
            </q-list>
        </q-drawer>
    </q-card>
</q-dialog>
</template>

<script>
import {
  defineComponent
} from 'vue'

import axios from 'axios'
import * as echarts from 'echarts'
export default defineComponent({
  name: 'PageIndex',
  data: function () {
    return {
      addwhiteListHash: false,
      whiteListPostData: {
        path: '',
        hash: '',
        reason: ''
      },
      processChainShowDetails: false,
      last_refresh: 360,
      processChainDetails: {
        hash: '',
        prams: '',
        hitRule: [],
        isWhite: false,
        whiteListReason: ''
      },
      thumbStyle: {
        right: '4px',
        borderRadius: '5px',
        backgroundColor: '#027be3',
        width: '5px',
        opacity: 0.75
      },
      barStyle: {
        right: '2px',
        borderRadius: '9px',
        backgroundColor: '#027be3',
        width: '9px',
        opacity: 0.2
      },
      threatStatistics: {
        all: 1,
        confirm: 0,
        ingore: 1,
        working: 0
      },
      Threatitems: [{
        title: '发现的威胁',
        icon: 'remove_red_eye',
        value: '200',
        color1: '#5064b5',
        color2: '#3e51b5'
      },
      {
        title: '确认的威胁',
        icon: 'flash_on',
        value: '500',
        color1: '#f37169',
        color2: '#f34636'
      },
      {
        title: '忽略的威胁',
        icon: 'texture',
        value: '50',
        color1: '#ea6a7f',
        color2: '#ea4b64'
      },
      {
        title: '进行中的威胁',
        icon: 'bar_chart',
        value: '1020',
        color1: '#a270b1',
        color2: '#9f52b1'
      }
      ],
      dialog: false,
      maximizedToggle: true,
      server_threat: {},
      select_chain_data: {}
    }
  },
  methods: {
    delete_white_hash (hash) {
      axios.get('/api/v1/del/white_list?hash=' + hash).then(res => {
        this.processChainDetails.isWhite = false
      })
    },
    query_white_hash (hash) {
      axios.get('/api/v1/query/white_list?hash=' + hash).then(res => {
        this.processChainDetails.isWhite = res.data.result === 1
      })
    },
    add_to_white_hash_pre (path, hash) {
      this.whiteListPostData = {
        path: path,
        hash: hash,
        reason: ''
      }
      this.addwhiteListHash = true
      console.log('addwhiteListHash', this.addwhiteListHash)
    },
    add_to_white_hash_post () {
      axios
        .post('/api/v1/set/white_list', this.whiteListPostData)
        .then((response) => {
          this.processChainDetails.isWhite = true
        })
    },
    set_chain_data (data) {
      if (data.path) {
        const str = data.path.split('\\')
        data.name = str[str.length - 1]
        console.log(data.name)
        for (const index in data.children) {
          this.set_chain_data(data.children[index])
        }
      }
    },
    draw_tree () {
      this.set_chain_data(this.select_chain_data)
      const dom = this.$refs.main_draw
      const myChart = echarts.init(dom)
      const option = {
        tooltip: {
          trigger: 'item',
          triggerOn: 'mousemove',
          formatter: function (params) {
            const contextData = params.data
            let result =
                            '<div>参数: ' +
                            contextData.params +
                            '</div>' +
                            '<div> hash: ' +
                            contextData.md5 +
                            '</div><div>命名规则列表: '
            if (contextData.operationlist.length === 0) {
              result += '无'
            }
            for (const key in contextData.operationlist) {
              result +=
                                ' ' + key + '[' + contextData.operationlist[key] + ']' + ' '
            }
            result += '</div>'
            return result
          }
        },
        series: [{
          roam: true,
          type: 'tree',
          id: 0,
          name: 'tree1',
          data: [this.select_chain_data],
          top: '5%',
          left: '15%',
          bottom: '22%',
          right: '20%',
          edgeShape: 'polyline',
          edgeForkPosition: '63%',
          initialTreeDepth: 60,
          lineStyle: {
            width: 2
          },
          label: {
            backgroundColor: '#fff',
            position: 'left',
            verticalAlign: 'middle',
            align: 'right'
          },
          leaves: {
            label: {
              position: 'right',
              verticalAlign: 'middle',
              align: 'left'
            }
          },
          emphasis: {
            focus: 'descendant'
          },
          symbolSize: [30, 30], // 宽40 高50
          symbol: 'image://data:image/png;base64, ',
          expandAndCollapse: false,
          animationDuration: 350,
          animationDurationUpdate: 450
        }]
      }
      myChart.setOption(option)
      myChart.on('click', params => {
        const data = params.data
        this.processChainDetails = {
          path: data.path,
          active: data.active,
          md5: data.md5,
          name: data.name,
          params: data.params,
          pid: data.pid,
          ppid: data.ppid,
          hitRules: data.operationlist,
          isWhite: false
        }
        this.query_white_hash(data.md5)
        this.processChainShowDetails = true
      })
    },
    search_vt (hash) {
      window.open('https://www.virustotal.com/gui/search/' + hash, '_blank')
    },
    delete_threat (threatId) {
      axios
        .get('/api/v1/get/process_chain/delete?id=' + threatId, {
          'Content-Type': 'application/json'
        })
        .then((response) => {
          this.get_clientids()
        })
    },
    handle_threat (threatId, handleType) {
      axios
        .get('/api/v1/get/process_chain/handle?id=' + threatId + '&handletype=' + handleType, {
          'Content-Type': 'application/json'
        })
        .then((response) => {
          this.get_clientids()
        })
    },
    show_details (threatId) {
      axios
        .get('/api/v1/get/process_chain/pull?id=' + threatId, {
          'Content-Type': 'application/json'
        })
        .then((response) => {
          const data = response.data
          if (data.data) {
            this.select_chain_data = data.data.chain.process_node
            this.dialog = true
            console.log('this.select_chain_data', this.select_chain_data)
            this.$nextTick(() => {
              this.draw_tree()
            })
          }
        })
    },
    get_threatStatistics () {
      axios
        .get('/api/v1/get/threat_statistics', {
          'Content-Type': 'application/json'
        })
        .then((response) => {
          const data = response.data
          if (data.data) {
            this.threatStatistics = data.data
            // Threatitems
            this.Threatitems[0].value = this.threatStatistics.all
            this.Threatitems[1].value = this.threatStatistics.confirm
            this.Threatitems[2].value = this.threatStatistics.ingore
            this.Threatitems[3].value = this.threatStatistics.working
          }
        })
    },
    get_clientids () {
      const queryType = this.$route.params.queryIndex
      const queryIndex = (queryType === null || queryType === undefined) ? 0 : queryType
      axios
        .get('/api/v1/get/process_chain/all?query_type=' + queryIndex, {
          'Content-Type': 'application/json'
        })
        .then((response) => {
          const data = response.data
          if (data.data) {
            this.server_threat = {
              data: []
            }
            this.server_threat.data = data.data
            this.get_threatStatistics()
          }
        })
    }
  },
  mounted () {
    this.get_clientids()
    setInterval(() => {
      this.last_refresh -= 1
      if (this.last_refresh <= 0) {
        this.get_clientids()
        this.last_refresh = 360
      }
    }, 1000)
    // this.draw_tree();
  },
  watch: {
    '$route' (val, from) { // 监听到路由（参数）改变
      // 拿到目标参数 val.query.typeCode 去再次请求数据接口
      this.get_clientids()
    }
  }
})
</script>
