<template>
  <div id="ip-tools">
    <h1>{{ $t('system.ip_tools') }}</h1>
    <p>{{ $t('views.tools.ip_tools.note') }}</p>
    <b-card :title="$t('views.tools.ip_tools.expand_compress_address')">
      <b-form-group :label="$t('system.ipv6_address')">
        <b-form-input v-model="ip_expand_compress" :placeholder="$t('system.ipv6_address')"
                      :state="checkIPExpandCompress" required></b-form-input>
        <b-form-invalid-feedback id="input-live-feedback-expand">
          {{ $t('system.invalid_ipv6') }}
        </b-form-invalid-feedback>
      </b-form-group>
      <b-form-group :label="$t('views.tools.ip_tools.expanded_address')">
        <CopyField :text="expandIP" code/>
      </b-form-group>
      <b-form-group :label="$t('views.tools.ip_tools.compressed_address')">
        <CopyField :text="compressIP" code/>
      </b-form-group>
    </b-card>
    <br>
    <b-card :title="$t('views.tools.ip_tools.subnet_calculator')">
      <b-form-group :label="$t('views.tools.ip_tools.ipv6_subnet')">
        <b-form-input v-model="subnet" :placeholder="$t('views.tools.ip_tools.ipv6_subnet')"
                      :state="checkIPSubnet" required></b-form-input>
        <b-form-invalid-feedback id="input-live-feedback-compress">
          {{ $t('views.tools.ip_tools.invalid_ipv6_subnet') }}
        </b-form-invalid-feedback>
      </b-form-group>
      <b-form-group :label="$t('system.start')">
        <CopyField :text="calculateRange.start" code/>
      </b-form-group>
      <b-form-group :label="$t('system.end')">
        <CopyField :text="calculateRange.end" code/>
      </b-form-group>
    </b-card>
    <br>
    <b-card :title="$t('views.tools.ip_tools.mac_to_eui64')">
      <b-form-group :label="$t('system.mac_address')">
        <b-form-input v-model="mac_to_local_link" :placeholder="$t('system.mac_address')"
                      :state="checkMacAddress" required></b-form-input>
        <b-form-invalid-feedback id="input-live-feedback-compress">
          {{ $t('views.tools.ip_tools.invalid_mac_address') }}
        </b-form-invalid-feedback>
      </b-form-group>
      <b-form-group :label="$t('system.network_address')">
        <div class="form-row m-0" >
          <b-form-select class="col-md-3 pr-4 mb-0" v-model="selected_eui_prefix" :options="available_eui_prefixes" v-if="this.$store.state.user"></b-form-select>
          <b-form-input :state="checkEUI_Subnet" class="mb-0" :class="[this.$store.state.user ? 'col-md-9' : 'col-md-12']" v-model="selected_eui_prefix"></b-form-input>
          <b-form-invalid-feedback id="input-live-feedback-compress">
            {{ isEUI64PrefixToLong ? $t('views.tools.ip_tools.eui64_prefix_too_long') : $t('views.tools.ip_tools.invalid_network_address') }}
          </b-form-invalid-feedback>
        </div>
      </b-form-group>
      <b-form-group :label="$t('views.tools.ip_tools.eui64')">
        <CopyField :text="macToEUI64" code/>
      </b-form-group>
    </b-card>
    <br>
    <b-card :title="$t('views.tools.ip_tools.ipv6_to_mac')">
      <b-form-group :label="$t('system.ipv6_address')">
        <b-form-input v-model="local_link_to_mac" :placeholder="$t('system.ipv6_address')"
                      :state="checkEUIIPv6Address" required></b-form-input>
        <b-form-invalid-feedback id="input-live-feedback-compress">
          <span v-if="checkEUI_IPv6">
            {{ $t('views.tools.ip_tools.ipv6_no_eui') }}
          </span>
          <span v-else>
            {{ $t('system.invalid_ipv6') }}
          </span>
        </b-form-invalid-feedback>
      </b-form-group>
      <b-form-group :label="$t('system.mac_address')">
        <CopyField :text="macAddress" code/>
      </b-form-group>
    </b-card>
    <br>
    <b-card :title="$t('views.tools.ip_tools.ipv4_mapped_ipv6')">
      <b-form-group :label="$t('system.ip_address')">
        <b-form-input v-model="v4_mapped_v6_input" :placeholder="$t('system.ip_address')"
                      :state="ipaddress().is_ip_v4(this.v4_mapped_v6_input)" required></b-form-input>
        <div class="form-row m-0" >
          <b-form-select class="col-md-3 pr-4 mb-0" v-model="selected_v4_mapped_v6_prefix" :options="available_eui_prefixes" v-if="this.$store.state.user"></b-form-select>
          <b-form-input :state="checkEUI_Subnet" class="mb-0" :class="[this.$store.state.user ? 'col-md-9' : 'col-md-12']" v-model="selected_v4_mapped_v6_prefix"></b-form-input>
          <b-form-invalid-feedback id="input-live-feedback-compress">
          <!-- TODO! -->
          <span v-if="checkEUI_IPv6">
            {{ $t('views.tools.ip_tools.ipv6_no_eui') }}
          </span>
          <span v-else>
            {{ $t('system.invalid_ip') }}
          </span>
        </b-form-invalid-feedback>
        </div>
      </b-form-group>
      <b-form-group :label="$t('system.ipv6_address')">
        <CopyField :text="v4_mapped_v6" code/>
      </b-form-group>
    </b-card>
  </div>
</template>

<script>
import CopyField from '@/components/CopyField.vue'
import Dns_bcdService from '@/api-services/dns_bcd.service'
import ipaddress from '@/util/ipaddress'

export default {
  name: 'IPv6',
  components: { CopyField },
  computed: {
    expandIP() {
      return ipaddress.normalize_ipv6(this.ip_expand_compress)
    },
    compressIP() {
      return ipaddress.abbreviate_ipv6(this.ip_expand_compress)
    },
    calculateRange() {
      if (ipaddress.check_ipv6_subnet(this.subnet)) {
        const split = this.subnet.split('/')
        return ipaddress.ipv6_range(split[0], split[1], 128)
      } else {
        return {
          start: '',
          end: '',
          size: 0
        }
      }
    },
    macToEUI64() {
      return ipaddress.mac_to_eui_ipv6(this.mac_to_local_link, this.selected_eui_prefix)
    },
    macAddress() {
      return ipaddress.eui_ipv6_to_mac(this.local_link_to_mac)
    },
    v4_mapped_v6() {
      // todo: add prefix selection
      // todo check prefix length...
      return ipaddress.map_v4_v6(this.selected_v4_mapped_v6_prefix, this.v4_mapped_v6_input)
    },
    checkIPExpandCompress() {
      return ipaddress.is_ip_v6(this.ip_expand_compress)
    },
    checkIPSubnet() {
      return ipaddress.check_ipv6_subnet(this.subnet)
    },
    checkMacAddress() {
      return ipaddress.is_mac_address(this.mac_to_local_link)
    },
    checkEUIIPv6Address() {
      return ipaddress.is_ip_v6(this.local_link_to_mac) && ipaddress.is_eui_ipv6(this.local_link_to_mac)
    },
    checkEUI_IPv6() {
      return ipaddress.is_ip_v6(this.local_link_to_mac)
    },
    checkEUI_Subnet() {
      return ipaddress.check_ipv6_subnet(this.selected_eui_prefix) && !this.isEUI64PrefixToLong
    },
    isEUI64PrefixToLong() {
      return ipaddress.get_ipv6_prefix_length(this.selected_eui_prefix) > 64
    }
  },
  methods: {
    create_option_from_subnet(subnet) {
      return { value: subnet.cidr, text: `${subnet.bcd} (${subnet.cidr})` }
    },
    ipaddress() {
      return ipaddress
    }
  },
  async created() {
    var result = []
    if (this.$store.state.user != null) {
      // load own subnets when user exists
      const resp = await Dns_bcdService.getOverview(this.$store.state.netdb_axios_config)
      const bcd2ou_lookup = {}
      const ous = {}
      for (const bcd_ou of resp.data.bcd2ou_list) {
        bcd2ou_lookup[bcd_ou.bcd_name] = bcd_ou
        ous[bcd_ou.ou_short_name] = []
      }

      resp.data.ip_subnet_list
        .filter(subnet => subnet.type === '6')
        .filter(subnet => ipaddress.get_ipv6_prefix_length(subnet.cidr) <= 64)
        .forEach(subnet => {
          ous[bcd2ou_lookup[subnet.bcd].ou_short_name].push(subnet)
        })

      result = Object.entries(ous)
        .filter(([, ou]) => ou.length > 0)
        .map(([name, ou]) => {
          return {
            label: name,
            options: ou.sort((s1, s2) => s1.bcd > s2.bcd).map(this.create_option_from_subnet)
          }
        })
        .sort((o1, o2) => o1.label.localeCompare(o2.label))
    }
    this.available_eui_prefixes = [{value: 'fe80::/10', text: 'Link-Local (fe80::/10)'}].concat(result)
  },
  data() {
    return {
      ip_expand_compress: '',
      subnet: '',
      mac_to_local_link: '',
      local_link_to_mac: '',
      selected_eui_prefix: 'fe80::/10',
      selected_v4_mapped_v6_prefix: '::ffff:0000:0000/96',
      available_eui_prefixes: [
        {value: 'fe80::/10', text: 'Link-Local (fe80::/10)'},
      ],
      v4_mapped_v6_input: '',
    }
  }
}
</script>

<style scoped>

</style>