text: /*
   *    (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
   *
   * Licensed 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 () {
    'use strict';
  
    /**
     * @ngdoc overview
     * @name horizon.dashboard.project.workflow.keypair.create-keypair-service
     *
     * @description
     * Service to handle creating keypairs and downloading their private keys.
     * Please note, the implementation has quirks due to what features are
     * available in which browsers.  As a result, the implementation involves
     * using iframes to specify downloads.  Since the API does not allow the
     * full retrieval of the key pair after creation, and the URL retrieved in
     * an iframe must be a GET method, and the fact that we shouldn't pass
     * data as part of the URL (because it is potentially logged and contains
     * private key data), we have to make the actual API call when performing
     * the GET.  This also means that if the user misses the download for some
     * reason, we need to provide the ability to regenerate the key pair,
     * although that is not a feature of this service.
     */
  
    angular
      .module('horizon.app.core.openstack-service-api')
      .factory('horizon.app.core.openstack-service-api.keypair-download-service',
        keypairDownloadService);
  
    keypairDownloadService.$inject = [
      '$document',
      'horizon.app.core.openstack-service-api.nova',
      '$q',
      '$timeout'
    ];
  
    function keypairDownloadService($document, novaAPI, $q, $timeout) {
  
      var service = {
        createAndDownloadKeypair: createAndDownloadKeypair
      };
  
      return service;
  
      /**
       * @ngdoc function
       * @name createAndDownloadKeypair
       *
       * @description
       * This function performs the actions necessary to begin a download
       * of a newly created key pair.  The given name will be used as the
       * logical name of the key pair and will be used to make a file-system-
       * friendly filename.
       * In this implementation, for browser compatibility reasons, the
       * download is achieved by creating an iframe with the given path for
       * the create API call given, so the results are streamed directly to the
       * client.  This is not ideal but is due to lack of support in IE for
       * features like the data: protocol.  The iframes require that an element
       * with the class of 'download-iframes' is present.
       *
       * @param {string} name The desired name for the key pair
       * @returns {promise} A promise resolving if true, rejecting with error
       */
      function createAndDownloadKeypair(name) {
        addDOMResource(name);
        return verifyCreatedPromise(name);
      }
  
      /**
       * @ngdoc function
       * @name addDOMResource
       *
       * @description
       * This adds an iframe to the body of the current document, using
       * the appropriate URL for the API to create/download the new key pair.
       *
       * @param {string} keypairName The desired name for the key pair
       * @returns {undefined} Returns nothing
       */
      function addDOMResource(keypairName) {
        var url = novaAPI.getCreateKeypairUrl(keypairName);
        var iframe = angular.element("<iframe></iframe>");
        iframe.attr('id', keypairName);
        iframe.attr('src', url);
        iframe.attr('style', 'display: none;');
        if ($document.find('.download-iframes').size() === 0) {
          var iframeContainer = angular.element('<div class="download-iframes"></div>');
          $document.find('body').append(iframeContainer);
        }
        $document.find('.download-iframes').append(iframe);
      }
  
      /**
       * @ngdoc function
       * @name verifyCreatedPromise
       *
       * @description
       * This function returns a promise that tries ten times to see if a
       * key pair of the given name exists in the key pair listing.  These
       * tries are one second apart.  Once it has been found, the promise
       * is resolved with the key pair data.  If it is not found within the
       * period, the promise is rejected.
       *
       * @param {string} name The name for the key pair
       * @returns {promise} A promise resolving if true, rejecting with error
       */
      function verifyCreatedPromise(name) {
        return $q(function doesKeypairExistPromise(resolve, reject) {
  
          doesKeypairExist(10);
  
          function doesKeypairExist(timesToCheck) {
            $timeout(function doesKeypairExistTimeout() {
              novaAPI.getKeypairs().then(function isKeypairInResponse(response) {
  
                var foundKeypairs = response.data.items.filter(function sameName(item) {
                  return item.keypair.name === name;
                });
  
                if (foundKeypairs.length === 1) {
                  resolve(foundKeypairs[0].keypair);
                  angular.element('.download-iframes #' + name).remove();
                } else if (timesToCheck > 1) {
                  doesKeypairExist(timesToCheck - 1);
                } else {
                  reject();
                  angular.element('.download-iframes #' + name).remove();
                }
  
              });
            },
            1000);
          }
  
        });
      }
  
    }
  
  })();
  