/*
 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.
*/

solrAdminApp.controller('AnalysisController',
  function($scope, $location, $routeParams, Luke, Analysis, Constants) {
      $scope.resetMenu("analysis", Constants.IS_COLLECTION_PAGE);

      $scope.refresh = function() {
        Luke.schema({core: $routeParams.core}, function(data) {
          $scope.fieldsAndTypes = [];
          for (var field in data.schema.fields) {
            $scope.fieldsAndTypes.push({
              group: "Fields",
              value: "fieldname=" + field,
              label: field});
          }
          for (var type in data.schema.types) {
            $scope.fieldsAndTypes.push({
              group: "Types",
              value: "fieldtype=" + type,
              label: type});
          }
          $scope.core = $routeParams.core;
        });

        $scope.parseQueryString();
        // @todo - set defaultSearchField either to context["analysis.fieldname"] or context["analysis.fieldtype"]

      };
      $scope.verbose = true;

      var getShortComponentName = function(longname) {
        var short = -1 !== longname.indexOf( '$' )
                         ? longname.split( '$' )[1]
                         : longname.split( '.' ).pop();
        return short.match( /[A-Z]/g ).join( '' );
      };

      var getCaptionsForComponent = function(data) {
        var captions = [];
        for (var key in data[0]) {
          key = key.replace(/.*#/,'');
          if (key != "match" && key!="positionHistory") {
            captions.push(key.replace(/.*#/,''));
          }
        }
        return captions;
      };

      var getTokensForComponent = function(data) {
        var tokens = [];
        var previousPosition = 0;
        var index=0;
        for (var i in data) {
          var tokenhash = data[i];
          var positionDifference = tokenhash.position - previousPosition;
          for (var j=positionDifference; j>1; j--) {
            tokens.push({position: tokenhash.position - j+1, blank:true, index:index++});
          }

          var token = {position: tokenhash.position, keys:[], index:index++};

          for (key in tokenhash) {
            if (key == "match" || key=="positionHistory") {
              //@ todo do something
            } else {
              token.keys.push({name:key, value:tokenhash[key]});
            }
          }
          tokens.push(token);
          previousPosition = tokenhash.position;
        }
        return tokens;
      };

      var extractComponents = function(data, result, name) {
        if (data) {
            result[name] = [];
            for (var i = 0; i < data.length; i += 2) {
                var component = {
                    name: data[i],
                    short: getShortComponentName(data[i]),
                    captions: getCaptionsForComponent(data[i + 1]),
                    tokens: getTokensForComponent(data[i + 1])
                };
                result[name].push(component);
            }
        }
      };

      var processAnalysisData = function(analysis, fieldOrType) {
        var fieldname;
        for (fieldname in analysis[fieldOrType]) {console.log(fieldname);break;}
        var response = {};
        extractComponents(analysis[fieldOrType][fieldname].index, response, "index");
        extractComponents(analysis[fieldOrType][fieldname].query, response, "query");
        return response;
      };

      $scope.updateQueryString = function() {

        var parts = $scope.fieldOrType.split("=");
        var fieldOrType = parts[0];
        var name = parts[1];

        if ($scope.indexText) {
            $location.search("analysis.fieldvalue", $scope.indexText);
        } else if ($location.search()["analysis.fieldvalue"]) {
            $location.search("analysis.fieldvalue", null);
        }
        if ($scope.queryText) {
          $location.search("analysis.query", $scope.queryText);
        } else if ($location.search()["analysis.query"]) {
            $location.search("analysis.query", null);
        }

        if (fieldOrType == "fieldname") {
          $location.search("analysis.fieldname", name);
          $location.search("analysis.fieldtype", null);
        } else {
          $location.search("analysis.fieldtype", name);
          $location.search("analysis.fieldname", null);
        }
        $location.search("verbose_output", $scope.verbose ? "1" : "0");
      };

      $scope.parseQueryString = function () {
          var params = {};
          var search = $location.search();

          if (Object.keys(search).length == 0) {
              return;
          }
          for (var key in search) {
              params[key]=search[key];
          }
          $scope.indexText = search["analysis.fieldvalue"];
          $scope.queryText = search["analysis.query"];
          if (search["analysis.fieldname"]) {
              $scope.fieldOrType = "fieldname=" + search["analysis.fieldname"];
              $scope.schemaBrowserUrl = "field=" + search["analysis.fieldname"];
          } else {
              $scope.fieldOrType = "fieldtype=" + search["analysis.fieldtype"];
              $scope.schemaBrowserUrl = "type=" + search["analysis.fieldtype"];
          }
          if (search["verbose_output"] == undefined) {
            $scope.verbose = true;
          } else {
            $scope.verbose = search["verbose_output"] == "1";
          }

          if ($scope.fieldOrType || $scope.indexText || $scope.queryText) {
            params.core = $routeParams.core;
            var parts = $scope.fieldOrType.split("=");
            var fieldOrType = parts[0] == "fieldname" ? "field_names" : "field_types";

            Analysis.field(params, function(data) {
              $scope.result = processAnalysisData(data.analysis, fieldOrType);
            });
          }
      };

      $scope.changeFieldOrType = function() {
        var parts = $scope.fieldOrType.split("=");
        if (parts[0]=='fieldname') {
          $scope.schemaBrowserUrl = "field=" + parts[1];
        } else {
          $scope.schemaBrowserUrl = "type=" + parts[1];
        }
      };

      $scope.toggleVerbose = function() {
        $scope.verbose = !$scope.verbose;
        $scope.updateQueryString();
      };

      $scope.refresh();
    }
);

/***************

function(error) {
  if (error.status == 404) {
    $scope.isHandlerMissing = true;
  } else {
    $scope.analysisError = error.error.msg;
  }
****/
