<template>
  <k-toolbar-item icon="compass" tooltip="Napp Pathfinder">
    <div class="scroll">
      <k-accordion>
        <k-accordion-item title="Best Paths">
         <k-input-auto id="source-input" :value.sync="source"
              title="Source:"
              tooltip="Source (format: dpid:port_number)"
              placeholder="Source" icon="circle-o"
              :candidates="dpids"
              @focus="fetch_dpids"
              @blur="onblur_source"
              ></k-input-auto>    
         <k-input-auto id="destination-input" :value.sync="destination"
              title="Destination:"
              tooltip="Destination (format: dpid:port_number)"
              placeholder="Destination" icon="circle-o"
              :candidates="dpids"
              @focus="fetch_dpids"
              @blur="onblur_source"
              ></k-input-auto>
         <k-select icon="link" title="Desired links:" :options="get_links"
          :value.sync ="desired_links"></k-select>
         <k-select icon="link" title="Undesired links:" :options="get_links"
          :value.sync ="undesired_links"></k-select>
          <div class="metric">
            <div class="checkbox">
              <k-checkbox :model.sync = "checked_list" :value = "'bandwidth'"></k-checkbox>
            </div>
            <div class="dropdown">
              <k-dropdown :options="metric_options['bandwidth']" 
               :value.sync="is_flexible.bandwidth"></k-dropdown>
            </div>
            <k-input icon="arrow-right" :action="function(val) {metrics.bandwidth = parseInt(val)}"></k-input>
          </div>
          <div class="metric">
            <div class="checkbox">
              <k-checkbox :model.sync = "checked_list" :value = "'reliability'"></k-checkbox>
            </div>
            <div class="dropdown">
              <k-dropdown :options="metric_options['reliability']" 
              :value.sync="is_flexible.reliability"></k-dropdown>
            </div>
            <k-input icon="arrow-right" :action="function(val) {metrics.reliability = parseInt(val)}"></k-input>
          </div>
          <div class="metric">
            <div class="checkbox">
              <k-checkbox :model.sync = "checked_list" :value = "'delay'"></k-checkbox>
            </div>
            <div class="dropdown">
              <k-dropdown :options="metric_options['delay']" 
              :value.sync="is_flexible.delay"></k-dropdown>
            </div>
            <k-input icon="arrow-right" :action="function(val) {metrics.delay = parseInt(val)}"></k-input>
          </div>
          <div class="metric">
            <div class="checkbox">
              <k-checkbox :model.sync = "checked_list" :value = "'utilization'"></k-checkbox>
            </div>
            <div class="dropdown">
              <k-dropdown :options="metric_options['utilization']" 
              :value.sync="is_flexible.utilization"></k-dropdown>
            </div>
            <k-input icon="arrow-right" :action="function(val) {metrics.utilization = parseInt(val)}"></k-input>
          </div>
          <div class="metric">
            <div class="checkbox">
              <k-checkbox :model.sync = "checked_list" :value = "'priority'"></k-checkbox>
            </div>
            <div class="dropdown">
              <k-dropdown :options="metric_options['priority']" 
              :value.sync="is_flexible.priority"></k-dropdown>
            </div>
            <k-input icon="arrow-right" :action="function(val) {metrics.priority = parseInt(val)}"></k-input>
          </div>
          <div class="metric">
            <div class="checkbox">
              <k-checkbox :model.sync = "checked_list" :value = "'ownership'"></k-checkbox>
            </div>
            <div class="dropdown">
              <k-dropdown :options="metric_options['ownership']" 
              :value.sync="is_flexible.ownership"></k-dropdown>
            </div>
          </div>
          <k-input icon="arrow-right" :value.sync="metrics.ownership"></k-input>

          <div class="metric">
            <div>
              <k-input icon="arrow-right" placeholder="Minimum flexible hits"
              :action="function (val) {minimum_flexible_hits = parseInt(val)}"></k-input>
            </div>
          </div>

          <div class="metric">
            <div class="dropdown">
              <k-dropdown title="SPF Attribute" :options="get_spf_attribute_options" 
              :value.sync="spf_attribute"></k-dropdown>
            </div>
          </div>

          <div class="metric">
            <div>
              <k-input icon="arrow-right" placeholder="SPF max number of paths"
              :action="function (val) {spf_max_paths = parseInt(val)}"></k-input>
            </div>
          </div>

          <div class="metric">
            <div>
              <k-input icon="arrow-right" placeholder="SPF path maximum cost"
              :action="function (val) {spf_max_path_cost = parseInt(val)}"></k-input>
            </div>
          </div>

           <div>
             <k-button icon="search" title="Search" :on_click="get_paths">
             </k-button>
           </div>

        </k-accordion-item>
      <k-accordion>
    </div>
  </k-toolbar-item>
</template>

<script>
module.exports = {
  methods: {
    get_paths (){
      var self = this
      var mandatory_metrics = {}
      var flexible_metrics = {}
      for(var checked of self.checked_list) {
        if (self.is_flexible[checked]) {
          flexible_metrics[checked] = self.metrics[checked]
        } else {
          mandatory_metrics[checked] = self.metrics[checked]
        }
      }

      $.ajax({
        async: true,
        dataType: "json",
        type: "POST",
        contentType: "application/json",
        data: JSON.stringify({"source": self.source,
               "destination": self.destination,
               "desired_links": self.desired_links,
               "undesired_links": self.undesired_links,
               "mandatory_metrics": mandatory_metrics,
               "flexible_metrics": flexible_metrics,
               "spf_attribute": self.spf_attribute,
               "spf_max_paths": self.spf_max_paths,
               "spf_max_path_cost": self.spf_max_path_cost,
               "minimum_flexible_hits": self.minimum_flexible_hits,
               }),

        url: this.$kytos_server_api + "kytos/pathfinder/v2",
        success: function(data) {
            if (data['paths'][0] !== undefined){
                self.paths = data['paths'];
            } else {
                self.paths = []
            }
          self.show();
        }
      });
    },
    get_topology(){
      var self = this
      $.ajax({
        async: true,
        dataType: "json",
        url: this.$kytos_server_api + "kytos/topology/v3",

        success: function(data) {
          self.switches = data['topology']['switches']
          self.links = data['topology']['links']
        }
      });

    },
    async fetch_dpids() {
      /*
      fetches a list of DPIDs (Datapath IDs) and interface information from an API endpoint, 
      then maps the DPIDs and interface names to a formatted string, 
      and finally sets the resulting array of strings as the dpids property of the component it belongs to. 
      If an error occurs during the fetch, it logs the error to the console
      */
  try {
    const response = await fetch('/api/kytos/topology/v3/interfaces');
    const data = await response.json();
    const dpids = Object.entries(data.interfaces).map(([key, value]) => {
      let item = key;
      if (value.name) {
        item = `${value.name} - ${item}`;
      }
      return item;
    });
    this.dpids = dpids;
  } catch (error) {
    console.error(error);
  }
},

onblur_source: function() {
  let source = this.source;
  if (source.lastIndexOf(':') > 0) {
    let [dpid, port] = source.split(':');
    this.source_dpid = dpid;
    this.source_port = port;
  }
},


    show() {
       var content = {
                      "component": 'kytos-pathfinder-k-info-panel-best_path',
                      "content": this.paths,
                      "icon": "compass",
                      "title": "Best Paths",
                      "subtitle": "by kytos/pathfinder"
                     }
       this.$kytos.$emit("showInfoPanel", content)

   }
  },

  computed: {
    metric_options(){
      var metric_options = {}

      var bandwidth_options = []
      var reliability_options = []
      var delay_options = []
      var utilization_options = []
      var priority_options = []
      var ownership_options = []
      var spf_attribute_options = []

      bandwidth_options.push({value: false, description: 'Bandwidth', selected: true});
      bandwidth_options.push({value: true, description: 'Bandwidth (Flexible)'});
      
      reliability_options.push({value: false, description: 'Reliability', selected: true});
      reliability_options.push({value: true, description: 'Reliability (Flexible)'});

      delay_options.push({value: false, description: 'Delay', selected: true});
      delay_options.push({value: true, description: 'Delay (Flexible)'});

      utilization_options.push({value: false, description: 'Utilization', selected: true});
      utilization_options.push({value: true, description: 'Utilization (Flexible)'});

      priority_options.push({value: false, description: 'Priority', selected: true});
      priority_options.push({value: true, description: 'Priority (Flexible)'});

      ownership_options.push({value: false, description: 'Ownership', selected: true});
      ownership_options.push({value: true, description: 'Ownership (Flexible)'});

      metric_options["bandwidth"] = bandwidth_options
      metric_options["reliability"] = reliability_options
      metric_options["delay"] = delay_options
      metric_options["utilization"] = utilization_options
      metric_options["priority"] = priority_options
      metric_options["ownership"] = ownership_options

      return metric_options;
    },
    get_interfaces(){
      var interfaces = []
      var switch_alias = ""
      var interface_alias = ""
      $.each(this.switches, function(key, value){
        switch_alias = ""
        if (value.metadata.aliases != undefined && value.metadata.aliases.length != 0){
          switch_alias = value.metadata.aliases[0]
        }
        $.each(value.interfaces, function(key, value){
          interface_alias = key
          if (value.metadata.alias != undefined && value.metadata.alias != ""){
            interface_alias = value.metadata.alias
          } else if (value.port_number != undefined){
            interface_alias = value.port_number
          }

          if (switch_alias != "" && interface_alias != key){
            renamed = switch_alias + ": " + interface_alias
            interfaces.push({value: key, description: renamed})
          } else {
            interfaces.push({value: key, description: key})
          }
        });
      });

      return interfaces;
    },
    get_links(){
      var links = []
      $.each(this.links, function(key, value){
        if (value.metadata.link_name !== undefined && value.metadata.link_name.length !== 0){
          links.push({value:value.id, description:value.metadata.link_name})
        } else {
          links.push({value:value.id, description:value.id});
        }
      });

      return links;
    },
    get_spf_attribute_options(){
      return [
        {value: "hop", description: "hop", selected: true},
        {value: "delay", description: "delay"},
        {value: "priority", description: "priority"}
      ];
    }
  },

  created(){
    this.get_topology();
  },

  data: function(){
    return {
      paths: [],
      switches: [],
      links: [],
      source: "",
      destination: "",
      desired_links: [],
      undesired_links: [],
      checked_list: [],
      dpids: [],
      hasAutoComplete: false,
      metrics:{
        bandwidth: 0,
        reliability: 0,
        delay: 0,
        utilization: 0,
        priority: 0,
        ownership: ""
      },
      is_flexible:{
        bandwidth: false,
        reliability: false,
        delay: false,
        utilization: false,
        priority: false,
        ownership: false
      },
      spf_attribute: "hop",
      spf_max_paths: 2,
      spf_max_path_cost: null,
      minimum_flexible_hits: null
    }
  }
}
</script>

<style type="text/css">
  body {overflow-y:hidden;}
  .scroll {overflow-y: auto; height:calc(100vh - 60px);}
  .metric {width:100%; overflow: hidden;}
  .checkbox {width:10%; float: left;}
  .dropdown {width:90%; float: left;}
  .text {font-size: 75%; float: left; margin-top: 1vh;}
  .title {font-size: 105%; font-weight: bold; float: left; margin-top: 1vh;}
</style>
