// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <a
    v-if="['vm', 'systemvm', 'router', 'ilbvm', 'vnfapp'].includes($route.meta.name) &&
           'listVirtualMachines' in $store.getters.apis &&
           'createConsoleEndpoint' in $store.getters.apis"
    @click="consoleUrl">
    <a-button
      style="margin-left: 5px"
      shape="circle"
      type="dashed"
      :size="size"
      :disabled="['Stopped', 'Restoring', 'Error', 'Destroyed'].includes(resource.state) ||
                 resource.hostcontrolstate === 'Offline'">
      <code-outlined v-if="!copyUrlToClipboard"/>
      <copy-outlined v-else />
    </a-button>
  </a>
</template>

<script>
import { SERVER_MANAGER } from '@/store/mutation-types'
import { postAPI } from '@/api'

export default {
  name: 'Console',
  props: {
    resource: {
      type: Object,
      required: true
    },
    size: {
      type: String,
      default: 'small'
    },
    copyUrlToClipboard: Boolean
  },
  data () {
    return {
      url: ''
    }
  },
  methods: {
    async consoleUrl () {
      try {
        const externalUrl = this.resource?.details?.['External:console_url']
        if (externalUrl) {
          this.url = externalUrl
          if (this.copyUrlToClipboard) {
            this.$copyText(this.url)
            this.$message.success({
              content: this.$t('label.copied.clipboard')
            })
          } else {
            window.open(this.url, '_blank')
          }
          return
        }

        const params = { virtualmachineid: this.resource.id }
        const json = await postAPI('createConsoleEndpoint', params)

        this.url = (json && json.createconsoleendpointresponse)
          ? json.createconsoleendpointresponse.consoleendpoint.url
          : '#/exception/404'

        if (json.createconsoleendpointresponse.consoleendpoint.success) {
          if (this.copyUrlToClipboard) {
            this.$copyText(this.url)
            this.$message.success({
              content: this.$t('label.copied.clipboard')
            })
          } else {
            window.open(this.url, '_blank')
          }
        } else {
          this.$notification.error({
            message: this.$t('error.execute.api.failed') + ' ' + 'createConsoleEndpoint',
            description: json.createconsoleendpointresponse.consoleendpoint.details
          })
        }
      } catch (error) {
        this.$notifyError(error)
      }
    }
  },
  computed: {
    server () {
      if (!this.$config.multipleServer) {
        return this.$config.apiBase.replace('/api', '')
      }
      const serverStorage = this.$localStorage.get(SERVER_MANAGER)
      const apiBase = serverStorage.apiBase.replace('/api', '')
      if (!serverStorage.apiHost || serverStorage.apiHost === '/') {
        return [location.origin, apiBase].join('')
      }
      return [serverStorage.apiHost, apiBase].join('')
    }
  }
}
</script>
