// 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-spin :spinning="loading">
    <a-form
      class="form-layout"
      layout="vertical"
      :ref="formRef"
      :model="form"
      :rules="rules"
      v-ctrl-enter="handleSubmit"
      @finish="handleSubmit">
      <a-alert style="margin-bottom: 5px" type="warning" show-icon>
        <template #message>
          <span v-html="$t('message.restart.vm.to.update.settings')" />
        </template>
      </a-alert>
      <a-form-item name="name" ref="name">
        <template #label>
          <tooltip-label :title="$t('label.name')" :tooltip="apiParams.name.description"/>
        </template>
        <a-input
          v-model:value="form.name"
          v-focus="true" />
      </a-form-item>
      <a-form-item name="displayname" ref="displayname">
        <template #label>
          <tooltip-label :title="$t('label.displayname')" :tooltip="apiParams.displayname.description"/>
        </template>
        <a-input v-model:value="form.displayname" />
      </a-form-item>
      <a-form-item name="ostypeid" ref="ostypeid">
        <template #label>
          <tooltip-label :title="$t('label.ostypeid')" :tooltip="apiParams.ostypeid.description"/>
        </template>
        <a-select
          showSearch
          optionFilterProp="label"
          :filterOption="(input, option) => {
            return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
          }"
          :loading="osTypes.loading"
          v-model:value="form.ostypeid">
          <a-select-option v-for="(ostype) in osTypes.opts" :key="ostype.id" :label="ostype.description">
            {{ ostype.description }}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item name="isdynamicallyscalable" ref="isdynamicallyscalable">
        <template #label>
          <tooltip-label :title="$t('label.isdynamicallyscalable')" :tooltip="apiParams.isdynamicallyscalable.description"/>
        </template>
        <a-switch v-model:checked="form.isdynamicallyscalable" />
      </a-form-item>
      <a-form-item name="haenable" ref="haenable" v-if="serviceOffering ? serviceOffering.offerha : false">
        <template #label>
          <tooltip-label :title="$t('label.haenable')" :tooltip="apiParams.haenable.description"/>
        </template>
        <a-switch v-model:checked="form.haenable" />
      </a-form-item>
      <a-form-item name="group" ref="group">
        <template #label>
          <tooltip-label :title="$t('label.group')" :tooltip="apiParams.group.description"/>
        </template>
        <a-auto-complete
          v-model:value="form.group"
          :filterOption="(input, option) => {
            return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
          }"
          :options="groups.opts" />
      </a-form-item>
      <a-form-item v-if="userDataEnabled">
        <template #label>
          <tooltip-label :title="$t('label.user.data')" :tooltip="apiParams.userdata.description"/>
        </template>
        <a-textarea v-model:value="form.userdata">
        </a-textarea>
      </a-form-item>
      <a-form-item v-if="extraConfigEnabled">
        <template #label>
          <tooltip-label :title="$t('label.extraconfig')" :tooltip="$t('label.extraconfig.tooltip')"/>
        </template>
        <a-textarea v-model:value="form.extraconfig"/>
      </a-form-item>
      <a-form-item ref="securitygroupids" name="securitygroupids" :label="$t('label.security.groups')" v-if="securityGroupsEnabled">
        <a-select
          mode="multiple"
          :placeholder="$t('label.select.security.groups')"
          v-model:value="form.securitygroupids"
          showSearch
          optionFilterProp="label"
          :filterOption="(input, option) => {
            return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
          }"
          :loading="securitygroups.loading"
          v-focus="true">
          <a-select-option v-for="securitygroup in securitygroups.opts" :key="securitygroup.id" :label="securitygroup.name ||  securitygroup.id">
            <div>
              {{ securitygroup.name ||  securitygroup.id }}
            </div>
          </a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item name="deleteprotection" ref="deleteprotection">
        <template #label>
          <tooltip-label :title="$t('label.deleteprotection')" :tooltip="apiParams.deleteprotection.description"/>
        </template>
        <a-switch v-model:checked="form.deleteprotection" />
      </a-form-item>
      <a-form-item name="showLeaseOptions" ref="showLeaseOptions" v-if="isLeaseEditable">
        <template #label>
          <tooltip-label :title="$t('label.lease.enable')" :tooltip="$t('label.lease.enable.tooltip')" />
        </template>
        <a-switch v-model:checked="showLeaseOptions" @change="onToggleLeaseData"/>
      </a-form-item>
      <a-row :gutter="12" v-if="showLeaseOptions">
        <a-col :md="12" :lg="12">
          <a-form-item name="leaseduration" ref="leaseduration">
            <template #label>
              <tooltip-label :title="$t('label.leaseduration')" />
            </template>
            <a-input
              v-model:value="form.leaseduration"
              :placeholder="$t('label.instance.lease.placeholder')"/>
          </a-form-item>
        </a-col>
        <a-col :md="12" :lg="12">
          <a-form-item name="leaseexpiryaction" ref="leaseexpiryaction">
            <template #label>
              <tooltip-label :title="$t('label.leaseexpiryaction')"  />
            </template>
            <a-select v-model:value="form.leaseexpiryaction" :defaultValue="expiryActions">
              <a-select-option v-for="action in expiryActions" :key="action" :label="action" />
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>

      <div :span="24" class="action-button">
        <a-button :loading="loading" @click="onCloseAction">{{ $t('label.cancel') }}</a-button>
        <a-button :loading="loading" ref="submit" type="primary" @click="handleSubmit">{{ $t('label.ok') }}</a-button>
      </div>
    </a-form>
  </a-spin>
</template>

<script>
import { ref, reactive, toRaw } from 'vue'
import { getAPI, postAPI } from '@/api'
import TooltipLabel from '@/components/widgets/TooltipLabel'

export default {
  name: 'EditVM',
  components: {
    TooltipLabel
  },
  props: {
    action: {
      type: Object,
      required: true
    },
    resource: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      serviceOffering: {},
      template: {},
      userDataEnabled: false,
      securityGroupsEnabled: false,
      loading: false,
      securitygroups: {
        loading: false,
        opts: []
      },
      osTypes: {
        loading: false,
        opts: []
      },
      groups: {
        loading: false,
        opts: []
      },
      isLeaseEditable: this.$store.getters.features.instanceleaseenabled && this.resource.leaseduration > -1,
      showLeaseOptions: false,
      leaseduration: this.resource.leaseduration === undefined ? 90 : this.resource.leaseduration,
      leaseexpiryaction: this.resource.leaseexpiryaction === undefined ? 'STOP' : this.resource.leaseexpiryaction,
      expiryActions: ['STOP', 'DESTROY'],
      naturalNumberRule: {
        type: 'number',
        validator: this.validateNumber
      }
    }
  },
  computed: {
    extraConfigEnabled () {
      return this.$store.getters.features.additionalconfigenabled
    },
    combinedExtraConfig () {
      if (!this.extraConfigEnabled || !this.resource.details) return ''
      const configs = Object.keys(this.resource.details)
        .filter(key => key.startsWith('extraconfig-'))
        .map(key => this.resource.details[key] || '')
        .filter(val => val.trim())
      return configs.join('\n\n')
    }
  },
  beforeCreate () {
    this.apiParams = this.$getApiParams('updateVirtualMachine')
  },
  created () {
    this.initForm()
    this.fetchData()
  },
  methods: {
    initForm () {
      this.formRef = ref()
      this.form = reactive({
        name: this.resource.name,
        displayname: this.resource.displayname,
        ostypeid: this.resource.ostypeid,
        isdynamicallyscalable: this.resource.isdynamicallyscalable,
        deleteprotection: this.resource.deleteprotection,
        group: this.resource.group,
        userdata: '',
        haenable: this.resource.haenable,
        leaseduration: this.resource.leaseduration,
        leaseexpiryaction: this.resource.leaseexpiryaction,
        extraconfig: this.combinedExtraConfig
      })
      this.rules = reactive({
        leaseduration: [this.naturalNumberRule]
      })
      this.showLeaseOptions = this.isLeaseEditable
    },
    fetchData () {
      this.fetchZoneDetails()
      this.fetchSecurityGroups()
      this.fetchOsTypes()
      this.fetchInstaceGroups()
      this.fetchServiceOfferingData()
      this.fetchTemplateData()
      this.fetchUserData()
    },
    fetchZoneDetails () {
      getAPI('listZones', {
        id: this.resource.zoneid
      }).then(response => {
        const zone = response?.listzonesresponse?.zone || []
        this.securityGroupsEnabled = zone?.[0]?.securitygroupsenabled || this.$store.getters.showSecurityGroups
      })
    },
    fetchSecurityGroups () {
      this.securitygroups.loading = true
      getAPI('listSecurityGroups', {
        zoneid: this.resource.zoneid
      }).then(json => {
        const items = json.listsecuritygroupsresponse.securitygroup || []
        if (items && items.length > 0) {
          for (let i = 0; i < items.length; i++) {
            this.securitygroups.opts.push(items[i])
          }
          this.securitygroups.opts.sort((a, b) => {
            if (a.name < b.name) return -1
            if (a.name > b.name) return 1
            return 0
          })
        }
      }).finally(() => {
        this.securitygroups.loading = false
      })
    },
    fetchServiceOfferingData () {
      const params = {}
      params.id = this.resource.serviceofferingid
      params.isrecursive = true
      var apiName = 'listServiceOfferings'
      getAPI(apiName, params).then(json => {
        const offerings = json?.listserviceofferingsresponse?.serviceoffering || []
        this.serviceOffering = offerings[0] || {}
      })
    },
    fetchTemplateData () {
      const params = {}
      params.id = this.resource.templateid
      params.isrecursive = true
      params.templatefilter = 'all'
      params.isready = true
      var apiName = 'listTemplates'
      getAPI(apiName, params).then(json => {
        const templateResponses = json.listtemplatesresponse.template
        this.template = templateResponses[0]
      })
    },
    fetchDynamicScalingVmConfig () {
      const params = {}
      params.name = 'enable.dynamic.scale.vm'
      params.zoneid = this.resource.zoneid
      var apiName = 'listConfigurations'
      getAPI(apiName, params).then(json => {
        const configResponse = json.listconfigurationsresponse.configuration
        this.dynamicScalingVmConfig = configResponse[0]?.value === 'true'
      })
    },
    canDynamicScalingEnabled () {
      return this.template.isdynamicallyscalable && this.serviceOffering.dynamicscalingenabled && this.dynamicScalingVmConfig
    },
    isDynamicScalingEnabled () {
      return this.template.isdynamicallyscalable && this.serviceOffering.dynamicscalingenabled && this.$store.getters.features.dynamicscalingenabled
    },
    fetchOsTypes () {
      this.osTypes.loading = true
      this.osTypes.opts = []
      getAPI('listOsTypes').then(json => {
        this.osTypes.opts = json.listostypesresponse.ostype || []
      }).catch(error => {
        this.$notifyError(error)
      }).finally(() => { this.osTypes.loading = false })
    },
    fetchInstaceGroups () {
      this.groups.loading = true
      this.groups.opts = []
      const params = {
        domainid: this.$store.getters.userInfo.domainid,
        listall: true
      }
      if (this.$store.getters.project && this.$store.getters.project.id) {
        params.projectid = this.$store.getters.project.id
      } else {
        params.account = this.$store.getters.userInfo.account
      }
      getAPI('listInstanceGroups', params).then(json => {
        const groups = json.listinstancegroupsresponse.instancegroup || []
        groups.forEach(x => {
          this.groups.opts.push({ id: x.name, value: x.name })
        })
      }).catch(error => {
        this.$notifyError(error)
      }).finally(() => { this.groups.loading = false })
    },
    decodeUserData (userdata) {
      const decodedData = Buffer.from(userdata, 'base64')
      return decodedData.toString('utf-8')
    },
    fetchUserData () {
      let networkId
      this.resource.nic.forEach(nic => {
        if (nic.isdefault) {
          networkId = nic.networkid
        }
      })
      if (!networkId) {
        return
      }
      const listNetworkParams = {
        id: networkId,
        listall: true
      }
      getAPI(`listNetworks`, listNetworkParams).then(json => {
        json.listnetworksresponse.network[0].service.forEach(service => {
          if (service.name === 'UserData') {
            this.userDataEnabled = true

            const listVmParams = {
              id: this.resource.id,
              userdata: true,
              listall: true
            }
            getAPI('listVirtualMachines', listVmParams).then(json => {
              this.form.userdata = atob(json.listvirtualmachinesresponse.virtualmachine[0].userdata || '')
            })
          }
        })
      })
    },
    handleSubmit () {
      this.formRef.value.validate().then(() => {
        const values = toRaw(this.form)
        const params = {}
        params.id = this.resource.id
        params.name = values.name
        params.displayname = values.displayname
        params.ostypeid = values.ostypeid
        if (this.securityGroupsEnabled && Array.isArray(values.securitygroupids) && values.securitygroupids.length > 0) {
          params.securitygroupids = values.securitygroupids
        }
        if (values.isdynamicallyscalable !== undefined) {
          params.isdynamicallyscalable = values.isdynamicallyscalable
        }
        if (values.deleteprotection !== undefined) {
          params.deleteprotection = values.deleteprotection
        }
        if (values.haenable !== undefined) {
          params.haenable = values.haenable
        }
        if (values.group && values.group.length > 0) {
          params.group = values.group
        }
        if (values.userdata && values.userdata.length > 0) {
          params.userdata = this.$toBase64AndURIEncoded(values.userdata)
        }
        if (values.leaseduration !== undefined && (values.leaseduration === -1 || values.leaseduration > 0)) {
          params.leaseduration = values.leaseduration
          if (values.leaseexpiryaction !== undefined) {
            params.leaseexpiryaction = values.leaseexpiryaction
          }
        }
        if (values.extraconfig && values.extraconfig.length > 0) {
          params.extraconfig = encodeURIComponent(values.extraconfig)
        }
        this.loading = true

        postAPI('updateVirtualMachine', params).then(json => {
          this.$message.success({
            content: `${this.$t('label.action.edit.instance')} - ${values.name}`,
            duration: 2
          })
          this.$emit('refresh-data')
          this.onCloseAction()
        }).catch(error => {
          this.$notifyError(error)
        }).finally(() => { this.loading = false })
      }).catch(error => {
        this.formRef.value.scrollToField(error.errorFields[0].name)
      })
    },
    onCloseAction () {
      this.$emit('close-action')
    },
    onToggleLeaseData () {
      if (this.showLeaseOptions === false) {
        this.form.leaseduration = -1
        this.form.leaseexpiryaction = undefined
      } else {
        this.form.leaseduration = this.leaseduration
        this.form.leaseexpiryaction = this.leaseexpiryaction
      }
    },
    async validateNumber (rule, value) {
      if (value && (isNaN(value) || value <= 0)) {
        return Promise.reject(this.$t('message.error.number'))
      }
      return Promise.resolve()
    }
  }
}
</script>

<style scoped lang="less">
.form-layout {
  width: 80vw;

  @media (min-width: 600px) {
    width: 450px;
  }

  .action-button {
    text-align: right;
    margin-top: 20px;

    button {
      margin-right: 5px;
    }
  }
}
</style>
