// 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.
(function($, cloudStack) {
  /**
   * Zone details chart
   */
  cloudStack.uiCustom.systemChart = function(chartID) {
    /**
     * Make view all button
     */
    var viewAllButton = function(args) {
      var $viewAll = $('<div>').addClass('button view-all');
      var $label = $('<span>').addClass('view-all-label').html(args.label ? args.label : 'View all');
      var $browser = args.$browser;
      var action = args.action;
      // Launch a list view
      //var $multiple-click=$viewAll.data('multiple-click',false);
      $viewAll.click(function() {
        if ($viewAll.data('multiple-click')) return false;
        //@pranav-handling the multiple clicks by using a flag variable
        $viewAll.data('multiple-click', true);
        $browser.cloudBrowser('addPanel', {
          title: args.title,
          maximizeIfSelected: true,
          complete: function($newPanel) {
            $viewAll.data('multiple-click', false);
            action({ $panel: $newPanel });
          }
        });
      });

      $viewAll.append($label);

      return $viewAll;
    };

    /**
     * Chart button action generators
     */
    var actions = {
      /**
       * Makes a list view from given zone sub-section
       */
      listView: function(targetID, context) {
        return function(args) {
          var $elem = args.$panel;
          var listViewArgs = cloudStack.sections.system.subsections[targetID].listView;

          $elem.listView({
            context: context,
            listView: listViewArgs
          });
        };
      },

      providerListView: function(context) {
        return function(args) {
          var $elem = args.$panel;
          var listViewArgs = cloudStack.sections.system.naas.providerListView;

          $elem.listView({
            context: context,
            listView: listViewArgs
          });
        };
      },

      /**
       * Makes details for a given traffic type
       */
      trafficTypeDetails: function(targetID, context) {
        return function(args) {
          var $elem = args.$panel;
          var detailViewArgs = cloudStack.sections.system.naas.mainNetworks[targetID].detailView;

          $elem.detailView($.extend(true, {}, detailViewArgs, {
            $browser: $('#browser .container'),
            context: context
          }));
        };
      }
    };

    /**
     * Chart generators
     */
    var charts = {
      /**
       * Compute tab
       */
      compute: function(args) {
        var $chart = $('<div>');
        var $browser = $('#browser .container');
        var context = args.context;

        // Resource items
        var computeResources = {
          zone: {
            label: 'Zone'
          },

          pods: {
            label: 'Pods',
            viewAll: {
              action: actions.listView('pods', context)
            }
          },

          clusters: {
            label: 'Clusters',
            viewAll: {
              action: actions.listView('clusters', context)
            }
          },

          hosts: {
            label: 'Hosts',
            viewAll: {
              action: actions.listView('hosts', context)
            }
          },

          primaryStorage: {
            label: 'Primary Storage',
            viewAll: {
              action: actions.listView('primary-storage', context)
            }
          },

          ucs: {
            label: 'UCS',
            viewAll: {
              action: actions.listView('ucs', context)
            }
          },

          secondaryStorage: {
            label: 'Secondary Storage',
            viewAll: {
              action: actions.listView('secondary-storage', context)
            }
          }
        };


        var $computeResources = $('<ul>').addClass('resources');

        // Make resource items
        $.each(computeResources, function(id, resource) {
          var $li = $('<li>');
          var $label = $('<span>').addClass('label');

          $li.addClass(id);
          $label.html(resource.label);
          $label.appendTo($li);

          // View all
          if (resource.viewAll) {
            viewAllButton($.extend(resource.viewAll, {
              title: resource.label,
              $browser: $browser,
              context: context
            })).appendTo($li);
          }

          $li.appendTo($computeResources);
        });

        $chart.append($computeResources);

        return $chart;
      },

      network: function(args) {
        var $chart = $('<div>');
        var $browser = $('#browser .container');
        var $loading = $('<div>').addClass('loading-overlay');
        var context = args.context;
        var networkDataProvider = cloudStack.sections.system.naas.networks.dataProvider;
        var trafficTypeDataProvider = cloudStack.sections.system.naas.trafficTypes.dataProvider;

        $loading.appendTo($chart);

        var renderChart = function(args) {
          var $targetChart = args.$chart ? args.$chart : $chart;
          var targetContext = $.extend(true, {}, context, {
            physicalNetworks: [args.data]
          });

          // Get traffic type data
          trafficTypeDataProvider({
            context: targetContext,
            response: {
              success: function(args) {
                var $networkChart = $('<div>').addClass('system-network-chart');
                var $trafficTypes = $('<ul>').addClass('resources traffic-types');

                $loading.remove();

                var trafficTypes = {
                  'public': {
                    label: _l('label.public'),
                    configure: {
                      action: actions.trafficTypeDetails('public', targetContext)
                    }
                  },

                  'guest': {
                    label: _l('label.guest'),
                    configure: {
                      action: actions.trafficTypeDetails('guest', targetContext)
                    }
                  },

                  'management': {
                    label: _l('label.management'),
                    configure: {
                      action: actions.trafficTypeDetails('management', targetContext)
                    }
                  },

                  'storage': {
                    label: _l('label.storage'),
                    configure: {
                      action: actions.trafficTypeDetails('storage', targetContext)
                    }
                  },

                  'providers': {
                    label: _l('label.network.service.providers'),
                    ignoreChart: true,
                    dependsOn: 'guest',
                    configure: {
                      action: actions.providerListView(targetContext)
                    }
                  }
                };

                var validTrafficTypes = $.map(args.data, function(trafficType) {
                  return trafficType.name.toLowerCase();
                });

                // Make traffic type elems
                $.each(trafficTypes, function(id, trafficType) {
                  if ($.inArray(id, validTrafficTypes) == -1) { //if it is not a valid traffic type
                    if(trafficType.dependsOn != null && trafficType.dependsOn.length > 0) { //if it has dependsOn
                      if($.inArray(trafficType.dependsOn, validTrafficTypes) == -1) { //if its dependsOn is not a valid traffic type, either
                        return true; //skip this item
                      }
                      //else, if its dependsOn is a valid traffic type, continue to Make list item	(e.g. providers.dependsOn is 'guest')
                    }
                    else {
                      return true; //if it doesn't have dependsOn, skip this item
                    }
                  }

                  // Make list item
                  var $li = $('<li>').addClass(id);
                  var $label = $('<span>').addClass('label').html(trafficType.label);
                  var $configureButton = viewAllButton($.extend(trafficType.configure, {
                    label: _l('label.configure'),
                    title: trafficType.label,
                    $browser: $browser,
                    targetContext: targetContext
                  }));

                  $li.append($label, $configureButton);
                  $li.appendTo($trafficTypes);

                  // Make chart
                  if (trafficType.ignoreChart)
                    return true;

                  var $targetChartItem = $('<div>').addClass('network-chart-item').addClass(id);
                  $targetChartItem.appendTo($networkChart);
                });

                var $switchIcon = $('<div>').addClass('network-switch-icon').append(
                  $('<span>').html('L2/L3 switch')
                );
                var $circleIcon = $('<div>').addClass('base-circle-icon');

                $targetChart.append($trafficTypes, $switchIcon, $networkChart, $circleIcon);
              }
            }
          });
        };

        // Get network data
        networkDataProvider({
          context: context,
          response: {
            success: function(args) {
              var data = args.data;
              var actionFilter = args.actionFilter;

              $chart.listView({
                listView: $.extend(true, {}, cloudStack.sections.system.naas.networks.listView, {
                  dataProvider: function(args) {
                    args.response.success({ actionFilter: actionFilter, data: data });
                  },
                  detailView: {
                    noCompact: true,
                    tabs: {
                      network: {
                        title: 'Network',
                        custom: function(args) {
                          var $chart = $('<div>').addClass('system-chart network');

                          renderChart({
                            $chart: $chart,
                            data: args.context.physicalNetworks[0]
                          });

                          return $chart;
                        }
                      }
                    }
                  }
                })
              });
              $loading.remove();
            }
          }
        });

        return $chart;
      },

      resources: function(args) {
        var $chart = $('<div>').addClass('dashboard admin');
        var $chartItems = $('<ul>');
        var $stats = $('<div>').addClass('stats');
        var $container = $('<div>').addClass('dashboard-container head');
        var $top = $('<div>').addClass('top');
        var $title = $('<div>').addClass('title').append($('<span>').html(_l('label.system.wide.capacity')));

        var chartItems = {
          // The keys are based on the internal type ID associated with each capacity
          0: { name: _l('label.memory') },
          1: { name: _l('label.cpu') },
          2: { name: _l('label.storage') },
          3: { name: _l('label.primary.allocated') },
          6: { name: _l('label.secondary.storage') },
          9: { name: _l('label.local.storage') },
          4: { name: _l('label.public.ips') },
          5: { name: _l('label.management.ips') },
          8: { name: _l('label.direct.ips') },
          7: { name: _l('label.vlan') }
        };

        $top.append($title);
        $container.append($top, $stats.append($chartItems));
        $chart.append($container);
        var $loading = $('<div>').addClass('loading-overlay').prependTo($chart);

        cloudStack.sections.system.zoneDashboard({
          context: args.context,
          response: {
            success: function(args) {
              $loading.remove();
              $.each(chartItems, function(id, chartItem) {
                var data = args.data[id] ? args.data[id] : {
                  used: 0,
                  total: 0,
                  percent: 0
                };
                var $item = $('<li>');
                var $name = $('<div>').addClass('name').html(chartItem.name);
                var $value = $('<div>').addClass('value');
                var $content = $('<div>').addClass('content').html('Allocated: ');
                var $allocatedValue = $('<span>').addClass('allocated').html(data.used);
                var $totalValue = $('<span>').addClass('total').html(data.total);
                var $chart = $('<div>').addClass('chart');
                var $chartLine = $('<div>').addClass('chart-line')
                      .css({ width: '0%' })
                      .animate({ width: data.percent + '%' });
                var $percent = $('<div>').addClass('percentage');
                var $percentValue = $('<soan>').addClass('value').html(data.percent);

                $chartItems.append(
                  $item.append(
                    $name,
                    $value.append(
                      $content.append(
                        $allocatedValue,
                        ' / ',
                        $totalValue
                      )
                    ),
                    $chart.append($chartLine),
                    $percent.append($percentValue, '%')
                  )
                );
              });
            }
          }
        });

        return $chart;
      }
    };

    return function(args) {
      // Fix zone context naming
      args.context.zones = args.context.physicalResources;

      var $chart = charts[chartID](args).addClass('system-chart').addClass(chartID);

      return $chart;
    };
  };
})(jQuery, cloudStack);
