/**
 * 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.
 */
'use strict';

angular.module('ambariAdminConsole')
.controller('StackVersionsCreateCtrl', ['$scope', 'Stack', 'Utility', '$routeParams', '$location', '$timeout' ,'Alert', '$translate', 'Cluster', 'AddRepositoryModal', 'AddVersionModal', 'ConfirmationModal',
    function($scope, Stack, Utility, $routeParams, $location, $timeout, Alert, $translate, Cluster, AddRepositoryModal, AddVersionModal, ConfirmationModal) {
  var $t = $translate.instant;
  $scope.constants = {
    os: $t('versions.os')
  };
  $scope.createController = true;
  $scope.osList = [];
  $scope.stackIds = [];
  $scope.allVersions = [];
  $scope.networkLost = false;
  $scope.stackRepoUpdateLinkExists = true;
  $scope.skipValidation = false;
  $scope.useRedhatSatellite = false;

  $scope.clusterName = $routeParams.clusterName;
  $scope.subversionPattern = /^\d+\.\d+(-\d+)?$/;
  $scope.upgradeStack = {
    stack_name: '',
    stack_version: '',
    display_name: ''
  };

  $scope.publicOption = {
    index: 1,
    hasError: false
  };
  $scope.localOption = {
    index: 2,
    hasError: false
  };
  $scope.option1 = {
    index: 3,
    displayName: $t('versions.uploadFile'),
    file: '',
    hasError: false
  };
  $scope.option2 = {
    index: 4,
    displayName: $t('versions.enterURL'),
    url: $t('versions.defaultURL'),
    hasError: false
  };
  $scope.selectedOption = {
    index: 1
  };
  $scope.selectedLocalOption = {
    index: 3
  };

  /**
   * User can select ONLY one option to upload version definition file
   */
  $scope.toggleOptionSelect = function () {
    $scope.option1.hasError = false;
    $scope.option2.hasError = false;
  };
  $scope.isPublicRepoSelected = function () {
    if ($scope.selectedOption.index == $scope.publicOption.index) return true;
  };
  $scope.togglePublicLocalOptionSelect = function () {
    if ($scope.selectedOption.index == $scope.publicOption.index) {
      $scope.setInitialPublicRepoVersions();
    } else {
      $scope.clearRepoVersions();
    }
    $scope.validateRepoUrl();
  };
  $scope.setInitialPublicRepoVersions = function () {
    angular.forEach($scope.osList, function (os) {
      os.repositories.forEach(function(repo) {
        repo.Repositories.base_url = repo.Repositories.initial_base_url;
      });
    });
  };
  $scope.clearRepoVersions = function () {
    angular.forEach($scope.osList, function (os) {
      os.repositories.forEach(function(repo) {
        repo.Repositories.base_url = '';
      });
    });
  };
  $scope.clearOptionsError = function () {
    $scope.option1.hasError = false;
    $scope.option2.hasError = false;
  };
  $scope.readInfoButtonDisabled = function () {
    if ($scope.selectedOption.index == $scope.publicOption.index) return true;
    return $scope.option1.index == $scope.selectedLocalOption.index ? !$scope.option1.file : !$scope.option2.url;
  };
  $scope.isAddOsButtonDisabled = function () {
    var selectedCnt = 0;
    angular.forEach($scope.osList, function (os) {
      if (os.selected) {
        selectedCnt ++;
      }
    });
    return $scope.osList.length == selectedCnt || $scope.useRedhatSatellite;
  };

  $scope.allInfoCategoriesBlank = function () {
    return !$scope.upgradeStack.stack_name;
  };

  $scope.onFileSelect = function(e){
    if (e.files && e.files.length == 1) {
      var file = e.files[0];
      var reader = new FileReader();
      reader.onload = (function () {
        return function (e) {
          $scope.option1.file = e.target.result;
        };
      })(file);
      reader.readAsText(file);
    } else {
      $scope.option1.file = '';
    }
  };

  /**
   * On click handler for adding a new version
   */
  $scope.addVersion = function() {
    AddVersionModal.show($scope);
  };

  /**
   * Load selected file to current page content
   */
  $scope.readVersionInfo = function(){
    var data = {};
    var isXMLdata = false;
    if ($scope.option2.index == $scope.selectedLocalOption.index) {
      var url = $scope.option2.url;
      data = {
        "VersionDefinition": {
          "version_url": url
        }
      };
    } else if ($scope.option1.index == $scope.selectedLocalOption.index) {
      isXMLdata = true;
      // load from file browser
      data = $scope.option1.file;
    }

    return Stack.postVersionDefinitionFile(isXMLdata, data).then(function (versionInfo) {
      if (versionInfo.id && versionInfo.stackName && versionInfo.stackVersion) {
        Stack.getRepo(versionInfo.id, versionInfo.stackName, versionInfo.stackVersion)
          .then(function (response) {
            $scope.setVersionSelected(response);
        });
      }
    })
    .catch(function (data) {
      Alert.error($t('versions.alerts.readVersionInfoError'), data.message);
    });
  };

  /**
   * Load supported OS list
   */
  $scope.afterStackVersionRead = function () {
    Stack.getSupportedOSList($scope.upgradeStack.stack_name, $scope.upgradeStack.stack_version)
      .then(function (data) {
        var existingOSHash = {};
        angular.forEach($scope.osList, function (os) {
          if (angular.isUndefined(os.selected)) {
            os.selected = true;
          }
          existingOSHash[os.OperatingSystems.os_type] = os;

        });
        var operatingSystems = data.operating_systems;
        angular.forEach(operatingSystems, function (stackOs) {
          // if os not in the list, mark as un-selected, add this to the osList
          if (!existingOSHash[stackOs.OperatingSystems.os_type]) {
            stackOs.selected = false;
            stackOs.repositories.forEach(function(repo) {
              repo.Repositories.base_url = '';
              repo.Repositories.initial_base_url = '';
            });
            $scope.osList.push(stackOs);
          }
        });
        if ($scope.selectedOption.index == $scope.localOption.index) {
          $scope.clearRepoVersions();
          $scope.validateRepoUrl();
        }
      })
      .catch(function (data) {
        Alert.error($t('versions.alerts.osListError'), data.message);
      });
  };

  /**
   * On click handler for removing OS
   */
  $scope.removeOS = function() {
    if ($scope.useRedhatSatellite) {
      return;
    }
    this.os.selected = false;
    if (this.os.repositories) {
      this.os.repositories.forEach(function(repo) {
        repo.hasError = false;
      });
    }
  };
  /**
   * On click handler for adding new OS
   */
  $scope.addOS = function($event) {
    var dropdownEl = $event.target.parentElement.parentElement;
    // close the dopdown when an OS is added.
    $timeout(function () {
      dropdownEl.click();
    });

    this.os.selected = true;
    if (this.os.repositories) {
      this.os.repositories.forEach(function(repo) {
        repo.hasError = false;
      });
    }
  };

  /**
   * On click handler for adding a new repository
   */
  $scope.addRepository = function() {
    AddRepositoryModal.show($scope.osList, $scope.upgradeStack.stack_name, $scope.upgradeStack.stack_version, $scope.id);
  };

  $scope.validBaseUrlsExist = function () {
    var validBaseUrlsExist = true;
    if ($scope.osList) {
      $scope.osList.forEach(function(os) {
        if (os.repositories && os.selected) {
          os.repositories.forEach(function(repo) {
            if (repo.invalidBaseUrl) {
              validBaseUrlsExist = false;
            }
          })
        }
      });
    }
    return validBaseUrlsExist;
  };


  $scope.isSaveButtonDisabled = function() {
    var enabled = false;
    $scope.osList.forEach(function(os) {
      if (os.selected) {
        enabled = true
      }
    });
    var isRedhatSatelliteSelected = $scope.useRedhatSatellite;
    return !(isRedhatSatelliteSelected || (enabled && $scope.validBaseUrlsExist()));
  };

  $scope.defaulfOSRepos = {};

  $scope.save = function () {
    $scope.editVersionDisabled = true;
    delete $scope.updateObj.href;
    $scope.updateObj.operating_systems = [];
    angular.forEach($scope.osList, function (os) {
      os.OperatingSystems.ambari_managed_repositories = !$scope.useRedhatSatellite;
      if (os.selected) {
        $scope.updateObj.operating_systems.push(os);
      }
    });

    var skip = $scope.skipValidation || $scope.useRedhatSatellite;
    return Stack.validateBaseUrls(skip, $scope.osList, $scope.upgradeStack).then(function (invalidUrls) {
      if (invalidUrls.length === 0) {
        if ($scope.isPublicVersion) {
          var data = {
            "VersionDefinition": {
              "available": $scope.id
            }
          };
          var isXMLdata = false;
        } else {
          var data = $scope.data;
          var isXMLdata = $scope.isXMLdata;
        }

        if (!isXMLdata) {
          data.VersionDefinition.display_name = $scope.activeStackVersion.displayName;
        }

        var repoUpdate = {
          operating_systems: $scope.updateObj.operating_systems
        };
        Stack.postVersionDefinitionFile(isXMLdata, data, false).then(function (response) {
          var versionInfo = response.resources[0].VersionDefinition;
          if (versionInfo.id && versionInfo.stack_name && versionInfo.stack_version) {
            Stack.updateRepo(versionInfo.stack_name, versionInfo.stack_version, versionInfo.id, repoUpdate).then(function () {
              Alert.success($t('versions.alerts.versionCreated', {
                stackName: $scope.upgradeStack.stack_name,
                versionName: $scope.actualVersion
              }));
              $location.path('/stackVersions');
            }).catch(function (data) {
              Stack.deleteRepo(versionInfo.stack_name, versionInfo.stack_version, versionInfo.id);
              ConfirmationModal.show(
                $t('versions.register.error.header'),
                $t('versions.register.error.body'),
                null,
                null,
                true
              )
            });
          }
        })
        .catch(function (data) {
          Alert.error($t('versions.alerts.readVersionInfoError'), data.message);
        });
      } else {
        Stack.highlightInvalidUrls(invalidUrls);
      }
    });
  };

  $scope.updateRepoVersions = function () {
    var skip = $scope.skipValidation || $scope.useRedhatSatellite;
    return Stack.validateBaseUrls(skip, $scope.osList, $scope.upgradeStack).then(function (invalidUrls) {
      if (invalidUrls.length === 0) {
        Stack.updateRepo($scope.upgradeStack.stack_name, $scope.upgradeStack.stack_version, $scope.id, $scope.updateObj).then(function () {
          Alert.success($t('versions.alerts.versionEdited', {
            stackName: $scope.upgradeStack.stack_name,
            versionName: $scope.actualVersion,
            displayName: $scope.repoVersionFullName
          }));
          $location.path('/stackVersions');
        }).catch(function (data) {
          Alert.error($t('versions.alerts.versionUpdateError'), data.message);
        });
      } else {
        Stack.highlightInvalidUrls(invalidUrls);
      }
    });
  };

  $scope.cancel = function () {
    $scope.editVersionDisabled = true;
    $location.path('/stackVersions');
  };

  $scope.clearErrors = function() {
    if ($scope.osList) {
      $scope.osList.forEach(function(os) {
        if (os.repositories) {
          os.repositories.forEach(function(repo) {
            repo.hasError = false;
          })
        }
      });
    }
    if ($scope.useRedhatSatellite) {
      ConfirmationModal.show(
          $t('common.important'),
          {
            "url": 'views/modals/BodyForUseRedhatSatellite.html'
          }
      ).catch(function () {
        $scope.useRedhatSatellite = !$scope.useRedhatSatellite;
      });
    }
  };

  $scope.showPublicRepoDisabledDialog = function() {
    ConfirmationModal.show(
      $t('versions.networkIssues.publicDisabledHeader'),
      {
        "url": 'views/modals/publicRepoDisabled.html'
      },
      $t('common.controls.ok'),
      $t('common.controls.cancel'),
      true
    )
  };

  $scope.onRepoUrlChange = function (repository) {
    $scope.clearError(repository);
    $scope.setInvalidUrlError(repository);
  };

  $scope.undoChange = function(repo) {
    if ($scope.selectedOption.index == 1) {
      repo.Repositories.base_url = repo.Repositories.initial_base_url;
    } else {
      repo.Repositories.base_url = '';
    }
  };

  $scope.clearError = function(repository) {
    repository.hasError = false;
  };

  $scope.setInvalidUrlError = function (repository) {
    repository.invalidBaseUrl =  !$scope.isValidRepoBaseUrl(repository.Repositories.base_url);
  };
  /**
   * Validate base URL
   * @param {string} value
   * @returns {boolean}
   */
  $scope.isValidRepoBaseUrl = function (value) {
    var remotePattern = /^(?:(?:https?|ftp):\/{2})(?:\S+(?::\S*)?@)?(?:(?:(?:[\w\-.]))*)(?::[0-9]+)?(?:\/\S*)?$/,
      localPattern = /^file:\/{2,3}([a-zA-Z][:|]\/){0,1}[\w~!*'();@&=\/\\\-+$,?%#.\[\]]+$/;
    return remotePattern.test(value) || localPattern.test(value);
  };

  $scope.hasValidationErrors = function() {
    var hasErrors = false;
    if ($scope.osList) {
      $scope.osList.forEach(function(os) {
        if (os.repositories) {
          os.repositories.forEach(function(repo) {
            if (repo.hasError) {
              hasErrors = true;
            }
          })
        }
      });
    }
    return hasErrors;
  };


  $scope.setVersionSelected = function (version) {
    var response = version;
    $scope.id = response.id;
    $scope.isPatch = response.type == 'PATCH';
    $scope.stackNameVersion = response.stackNameVersion || $t('common.NA');
    $scope.displayName = response.displayName || $t('common.NA');
    $scope.actualVersion = response.repositoryVersion || response.actualVersion || $t('common.NA');
    $scope.isPublicVersion = response.showAvailable == true;
    $scope.updateObj = response.updateObj;
    $scope.upgradeStack = {
      stack_name: response.stackName,
      stack_version: response.stackVersion,
      display_name: response.displayName || $t('common.NA')
    };
    $scope.services = response.services.filter(function (service) {
          var skipServices = ['MAPREDUCE2', 'GANGLIA', 'KERBEROS'];
          return skipServices.indexOf(service.name) === -1;
        }) || [];
    $scope.repoVersionFullName = response.repoVersionFullName;
    $scope.osList = response.osList;

    // load supported os type base on stack version
    $scope.afterStackVersionRead();
  };

  $scope.selectRepoInList = function() {
    $scope.selectedPublicRepoVersion = this.version;
    $scope.setVersionSelected(this.version);
  };

  $scope.onStackIdChange = function () {
    $scope.setStackIdActive(this.stack);
    $scope.setVisibleStackVersions($scope.allVersions);
    $scope.setVersionSelected($scope.activeStackVersion);
  };

  $scope.setStackIdActive =  function (stack) {
    angular.forEach($scope.stackIds, function(_stack){
      _stack.isSelected = false;
    });
    stack.isSelected = true;
  };

  $scope.setStackIds = function(stacks) {
    var stackIds = [];
    // sort stacks as per per {stack_name}-{stack_version}
    stacks.sort(function(a,b){
      if (a.stackName === b.stackName) {
        var aStackVersion = parseFloat(a.stackVersion);
        var bStackVersion = parseFloat(b.stackVersion);
        if (aStackVersion === bStackVersion) {
          // sort numerically as per per {repository_version}
          return Utility.compareVersions(a.repositoryVersion, b.repositoryVersion);
        } else {
          //sort numerically as per per {stack_version}
          return aStackVersion > bStackVersion;
        }
      } else {
        //sort lexicographically as per per {stack_name}
        return  (a.stackName > b.stackName);
      }
    }).reverse();
    angular.forEach(stacks, function (stack) {
      stackIds.push(stack.stackNameVersion);
    });
    $scope.stackIds = stackIds.filter(function(item, index, self){
      return self.indexOf(item) === index;
    }).map(function(item){
      return {
        stackNameVersion: item,
        isSelected: false
      };
    });
    $scope.stackIds[0].isSelected = true;
  };

  $scope.setActiveVersion = function () {
    $scope.activeStackVersion = this.version;
    $scope.setVersionSelected($scope.activeStackVersion);
  };

  $scope.setVisibleStackVersions = function (versions) {
    var activeStackId = $scope.stackIds.find(function(item){
      return item.isSelected === true;
    });
    angular.forEach(versions, function (item, index) {
      item.visible = (item.stackNameVersion === activeStackId.stackNameVersion);
    });
    $scope.activeStackVersion = versions.filter(function(item){
      return item.visible;
    })[0];
  };

  /**
   * Return true if at least one stacks have the repo URL link in the repoinfo.xml
   * @return boolean
   * */
  $scope.setStackRepoUpdateLinkExists = function (versions) {
    var stackRepoUpdateLinkExists = versions.find(function(_version){
      return _version.stackRepoUpdateLinkExists;
    });

    //Found at least one version with the stack repo update link
    if (stackRepoUpdateLinkExists){
      $scope.stackRepoUpdateLinkExists = true;
    } else {
      $scope.stackRepoUpdateLinkExists = false;
    }
  };

  $scope.setNetworkIssues = function (versions) {
   $scope.networkLost = !versions.find(function(_version){
     return !_version.stackDefault;
   });
    if ($scope.networkLost) {
      $scope.selectedOption.index = 2;
      $scope.clearRepoVersions();
    }
  };

  $scope.validateRepoUrl = function () {
    angular.forEach($scope.osList,function(os){
      if (os.repositories) {
        os.repositories.forEach(function(repo) {
          $scope.onRepoUrlChange(repo);
        });
      }
    });
  };

  $scope.updateCurrentVersionInput = function () {
    $scope.activeStackVersion.displayName = $scope.activeStackVersion.stackNameVersion + "." + angular.element('[name="version"]')[0].value;
  };

  $scope.fetchPublicVersions = function () {
    return Stack.allPublicStackVersions().then(function (versions) {
      if (versions && versions.length) {
        $scope.setStackIds(versions);
        $scope.setVisibleStackVersions(versions);
        $scope.allVersions = versions;
        $scope.selectedPublicRepoVersion = $scope.activeStackVersion;
        $scope.setVersionSelected($scope.activeStackVersion);
        $scope.setNetworkIssues(versions);
        $scope.setStackRepoUpdateLinkExists(versions);
        $scope.validateRepoUrl();
        $scope.availableStackRepoList = versions.length == 1 ? [] : versions;
      }
    });
  };

  $scope.fetchPublicVersions();
}]);
