<style scoped>
  .console{
    height: 100%;
    padding:5px 5px;
    background-color: black;
    position: relative;
  }
</style>
<template>
    <div :id="'ternimalContainer'+idIndex" class="console">
      <div :id="'terminal'+idIndex" style="height: 100%"></div>
      <fileDirectory :host="host" v-clickoutside="closeFileDir" :uuid="terminal.uuid" v-show="fileDirectoryShow" @close="showFileDir(false)" :fileDirectoryShow="fileDirectoryShow" ref="fileDirectory"/>
    </div>
</template>
<script>
import Terminal from '../common/js/Xterm'
import fileDirectory from './fileDirectory'
export default {
  name: 'console',
  components: {
    fileDirectory
  },
  props: {
    terminal: { },
    terminalType: { default: '1' },
    idIndex: {
      type: Number,
      default: 0
    },
    isFullScreen: {
      type: Boolean,
      default: false
    },
    fontSize: {}
  },
  data () {
    return {
      term: null,
      terminalSocket: null,
      termimalRows: 15,
      termimalHeight: 270,
      topMenuHeight: 30,
      dragHeigh: 8,
      minRow: 1,
      fontSpaceHeight: 2, // 一行高度=fontSize+fontSpaceHeight
      obj: {
        id: 2
      },
      isInit: false,
      successBackContent: 'Connecting to',
      failBackContent: 'Sorry',
      connectFailContent: 'Connection failed',
      welcomeBackContent: 'Welcome',
      psdCont: 'password: ',
      conFinish: false,
      conSuccessNum: 0,
      inputSecret: false,
      userName: '',
      fileDirectoryShow: false,
      host: ''
    }
  },
  watch: {
  },
  methods: {
    prompt (term) {
      term.write('\r\n ')// term.write('\r\n~$ ');
    },
    resize (consoleHeigt, consoleWidth) {
      this.term.fit()
      this.resizeServiceConsole()
    },
    resizeServiceConsole () {
      const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
      const width = document.body.clientWidth// 可视宽度
      const height = parseInt(consoleBox.offsetHeight)
      const winStyle = {
        width: width,
        height: height,
        cols: this.term.cols, // cols和rows在resizeConsole方法已经设置
        rows: this.term.rows
      }
      this.$post('terminal/resize', winStyle).then(response => {
        if (response.code === 200) {
          this.term.fit()
        } else {
          this.$message.error(response.msg)
        }
      })
    },
    focusConsole () {
      this.term.focus()
    },
    beforeCreate () {
      let rows = this.termimalRows
      // const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
      const height = document.body.clientHeight// 高度
      // consoleBox.style.height = `${height - 120}px`
      rows = (height - this.topMenuHeight) / (this.fontSize + this.fontSpaceHeight)
      rows = parseInt(rows)
      const terminalContainer = document.getElementById('terminal' + this.idIndex)
      this.term = new Terminal({
        rows: rows, // 15行大概300px高，无法设置heigh，只能设置rows
        cursorStyle: 'block', // 光标样式  null | 'block' | 'underline' | 'bar'
        disableStdin: false, // 是否应禁用输入
        fontSize: this.fontSize
      })
      this.term.open(terminalContainer)
      this.term.focus()
      const params = {
        width: this.terminal.width,
        height: this.terminal.height,
        cols: this.terminal.cols,
        rows: this.terminal.rows,
        host: this.$loadsh.get(this.terminal, 'custom.host', ''),
        port: this.$loadsh.get(this.terminal, 'custom.port', ''),
        assetId: this.$loadsh.get(this.terminal, 'assetId', ''),
        accountId: this.$loadsh.get(this.terminal, 'accountId', ''),
        authProtocol: this.$loadsh.get(this.terminal, 'custom.authProtocol', ''),
        authProtocolPort: this.$loadsh.get(this.terminal, 'custom.authProtocolPort', ''),
        authType: this.$loadsh.get(this.terminal, 'custom.authType', ''),
        authUsername: this.$loadsh.get(this.terminal, 'custom.authUsername', ''),
        authPin: this.$loadsh.get(this.terminal, 'custom.authPin', ''),
        authPriKey: this.$loadsh.get(this.terminal, 'custom.authPriKey', ''),
        authUserTip: this.$loadsh.get(this.terminal, 'custom.authUserTip', ''),
        authPinTip: this.$loadsh.get(this.terminal, 'custom.authPinTip', '')
      }
      this.$post('/terminal/login', params).then(res => {
        if (res.code == 200) {
          this.terminal.uuid = res.data.uuid
          this.$forceUpdate()
          this.terminal.userName = res.data.authUsername + '@' + res.data.host
          this.host = res.data.host
          this.create()
        } else {
          this.terminal.uuid = res.data.uuid
          this.terminal.userName = res.data.authUsername + '@' + res.data.host
          this.host = res.data.host
          params.name = this.terminal.name
          this.$emit('loginFail', params)
          this.$message.error(res.msg)
        }
      })
    },
    create () {
      const that = this
      const token = localStorage.getItem('nz-token')
      let baseUrl = JSON.parse(JSON.stringify(this.$axios.defaults.baseURL))
      const protocol = window.location.protocol.indexOf('https') > -1 ? 'wss' : 'ws'
      if (baseUrl.startsWith('/')) {
        baseUrl = `${protocol}://` + window.location.host + baseUrl
      } else {
        baseUrl = baseUrl.replace('http://', 'ws://').replace('https://', 'wss://')
      }
      let url = ''
      this.terminal.height = document.body.clientHeight - 100
      this.terminal.width = document.body.clientWidth
      if (this.terminal.type === 'asset') {
        url = baseUrl + '/terminal.ws?width=' + this.terminal.width + '&height=' + this.terminal.height + '&cols=' + this.terminal.cols + '&rows=' + this.terminal.rows + '&token=' + token + '&assetId=' + this.terminal.assetId + '&accountId=' + this.terminal.accountId + '&uuid=' + this.terminal.uuid
      } else if (this.terminal.type === 'custom') {
        url = baseUrl + '/terminal.ws?width=' + this.terminal.width + '&height=' + this.terminal.height + '&cols=' + this.terminal.cols + '&rows=' + this.terminal.rows + '&token=' + token + '&accountId=' + this.terminal.accountId + '&uuid=' + this.terminal.uuid
        Object.keys(this.terminal.custom).forEach(key => {
          if (this.terminal.custom[key]) {
            url += '&' + key + '=' + this.terminal.custom[key]
          }
        })
      }
      this.terminalSocket = new WebSocket(url)
      // 连接成功onclose
      this.terminalSocket.onopen = () => {
        this.terminal.isLogin = true
        this.isInit = true
      }
      // 登录后，你输入的内容从后台服务返回
      this.term.on('data', function (data) {
        /*
        let code = data.charCodeAt(0);
        if(code==13){
        }else {
          //that.term.write(data);
        } */
      })
      // 返回
      this.terminalSocket.onmessage = function (evt) {
        let backContent = evt.data
        const welComIndex = backContent.indexOf(that.welcomeBackContent)
        if (welComIndex > -1) { // 无服务器信息（只与nezha进行了连接）
          const connectResult = {
            title: '',
            color: 1
          }
          that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
        } else {
          const successContentIndex = backContent.indexOf(that.successBackContent)
          if (successContentIndex > -1) {
            // that.conFinish = true;
            const startIndex = successContentIndex + that.successBackContent.length + 1
            backContent = backContent.substring(startIndex)
            const endIndex = backContent.indexOf('\r\n')
            const title = backContent.substring(0, endIndex)
            const connectResult = {
              title: title,
              color: 2
            }
            that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
          } else { // 失败
            const failContentIndex = backContent.indexOf(that.failBackContent)
            const connectFailIndex = backContent.indexOf(that.connectFailContent)
            if (failContentIndex > -1) {
              // that.conFinish = true;
              const connectResult = {
                title: '',
                color: 3
              }
              that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
            } else if (connectFailIndex > -1) {
              const connectResult = {
                title: '',
                color: 3
              }
              that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
            }
          }
        }
      }
      // 关闭
      this.terminalSocket.onclose = () => {
        this.terminal.isLogin = false
        // 报错sorry的，还没来得及看信息就关闭
        // this.$emit("closeConsole",this.terminal.name);//
        this.term && this.term.setOption('disableStdin', true)
      }

      // 错误
      this.terminalSocket.onerror = (e) => {
        this.terminal.isLogin = false
      }
      // 选中 复制
      this.term.on('selection', function () {})
      this.term.attachCustomKeyEventHandler(function (ev) { })

      this.term.attach(this.terminalSocket)
      this.term._initialized = true
      // this.term.fit()// 自适应大小(使终端的尺寸和几何尺寸适合于终端容器的尺寸) 只是width
      this.$nextTick(() => { // 解决进入全屏和退出全屏是底部隐藏
        this.setFontSize(this.fontSize)
      })
    },

    closeSocket () {
      if (this.terminalSocket) {
        this.terminalSocket.close()
        this.terminalSocket = ''
      }
      if (this.term) {
        this.term.destroy()
      }
      // 初始化console的高度
      this.conFinish = false
    },
    setFontSize (fontSize) {
      this.term && this.term.setOption('fontSize', fontSize)
      const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
      const width = document.body.clientWidth// 可视宽度
      let height = parseInt(consoleBox.offsetHeight)
      if (height == null || !height) { height = this.termimalHeight }
      const winStyle = {
        width: width,
        height: height,
        cols: this.term.cols, // cols和rows在resizeConsole方法已经设置
        rows: this.term.rows
      }
      // 调整终端可视区域高度
      // document.getElementsByClassName('xterm-screen')[this.idIndex].style.height = height - 30 + 'px'
      this.$nextTick(() => {
        this.term.resize(this.term.cols, this.term.rows)
        this.$post('terminal/resize', winStyle).then(response => {
          if (response.code === 200) {
            this.term.fit()
          } else {
            this.$message.error(response.msg)
          }
        })
      })
    },
    reconnect () {
      this.terminal.isLogin = false
      this.closeSocket()
      this.term.off('selection')
      this.term.off('data')
      this.beforeCreate()
    },
    closeFileDir () {
      this.showFileDir(false)
    },
    showFileDir (show) {
      if (JSON.stringify(show) == JSON.stringify(this.fileDirectoryShow)) {
        return
      }
      if (show) {
        this.fileDirectoryShow = show
      }
      let animationClass = ''
      animationClass = show ? 'backInRight' : 'backOutRight'
      this.animateCSS(this.$refs.fileDirectory.$el, animationClass).then((message) => {
        this.fileDirectoryShow = show
      })
    },
    enterStr (message) {
      if (this.terminalSocket && this.terminal.isLogin) {
        this.terminalSocket.send(message)
        this.terminalSocket.send('\n')
        this.term.scrollToBottom()
      }
    }
  },
  mounted () {
    this.beforeCreate()
  },
  beforeDestroy () {
    this.closeSocket()
    this.term.off('selection')
    this.term.off('data')
  }
}
</script>
<style scoped lang="scss">

</style>
