(function() {
  /**
   * Page which displays a build package for a specific build.
   */
  angular.module('quayPages').config(['pages', function(pages) {
    pages.create('build-package', 'build-package.html', BuildPackageCtrl);
  }]);

  function BuildPackageCtrl($scope, Restangular, ApiService, DataFileService, $routeParams, $rootScope, $location, $timeout) {
    var namespace = $routeParams.namespace;
    var name = $routeParams.name;
    var buildid = $routeParams.buildid;

    var params = {
      'repository': namespace + '/' + name,
      'build_uuid': buildid
    };

    $scope.initializeTree = function() {
      if ($scope.drawn) {
        $scope.tree.notifyResized();
        return;
      }

      $scope.drawn = true;
      $timeout(function() {
        $scope.tree.draw('file-tree-container');
      }, 10);
    };

    var determineDockerfilePath = function() {
      var dockerfilePath = 'Dockerfile';
      var dockerfileFolder = ($scope.repobuild['subdirectory'] || '');
      if (dockerfileFolder[0] == '/') {
        dockerfileFolder = dockerfileFolder.substr(1);
      }
      if (dockerfileFolder && dockerfileFolder[dockerfileFolder.length - 1] != '/') {
        dockerfileFolder += '/';
      }
      dockerfilePath = dockerfileFolder + 'Dockerfile';
      return dockerfilePath;
    };

    var processBuildPack = function(uint8array) {
      var archiveread = function(files) {
        var getpath = function(file) {
          return file.path;
        };

        var findFile = function(path) {
          for (var i = 0; i < files.length; ++i) {
            var file = files[i];
            if (file.path == path) {
              return file;
            }
          }
          return null;
        };

        $scope.tree = new FileTree($.map(files, getpath));
        $($scope.tree).bind('fileClicked', function(e) {
          var file = findFile(e.path);
          if (file && file.canRead) {
            saveAs(file.toBlob(), file.name);
          }
        });

        var dockerfilePath = determineDockerfilePath();
        var dockerfile = findFile(dockerfilePath);
        if (dockerfile && dockerfile.canRead) {
          DataFileService.blobToString(dockerfile.toBlob(), function(result) {
            $scope.$apply(function() {
              $scope.dockerFilePath = dockerfilePath || 'Dockerfile';
              $scope.dockerFileContents = result;
            });
          });
        }

        $scope.loaded = true;
      };

      var notarchive = function() {
        DataFileService.arrayToString(uint8array, function(r) {
          $scope.dockerFilePath = 'Dockerfile';
          $scope.dockerFileContents = r;
          $scope.loaded = true;
        });
      };

      setTimeout(function() {
        $scope.$apply(function() {
          DataFileService.readDataArrayAsPossibleArchive(uint8array, archiveread, notarchive);
        });
      }, 0);
    };

    var downloadBuildPack = function(url) {
      $scope.downloadProgress = 0;
      $scope.downloading = true;
      startDownload(url);
    };

    var startDownload = function(url) {
      var onprogress = function(p) {
        $scope.downloadProgress = p * 100;
      };

      var onerror = function() {
        $scope.downloading = false;
        $scope.downloadError = true;
      };

      var onloaded = function(uint8array) {
        $scope.downloading = false;
        processBuildPack(uint8array);
      };

      DataFileService.downloadDataFileAsArrayBuffer($scope, url, onprogress, onerror, onloaded);
    };

    var getBuildInfo = function() {
      $scope.repository_build = ApiService.getRepoBuildStatus(null, params, true).then(function(resp) {
        if (!resp['is_writer']) {
          $rootScope.title = 'Unknown build';
          $scope.accessDenied = true;
          return;
        }

        $rootScope.title = 'Repository Build Pack - ' + resp['display_name'];
        $scope.repobuild = resp;
        $scope.repo = {
          'namespace': namespace,
          'name': name
        };

        downloadBuildPack(resp['archive_url']);
        return resp;
      });
    };

    getBuildInfo();
  }
})();