<commit_before>/*
 * Copyright (c) 2015-2016 Codenvy, S.A.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Codenvy, S.A. - initial API and implementation
 */
'use strict';

/**
 * This class is handling the service for viewing the IDE
 * @author <NAME>
 */
class IdeSvc {

  /**
   * Default constructor that is using resource
   * @ngInject for Dependency injection
   */
  constructor(cheAPI, $rootScope, lodash, $mdDialog, userDashboardConfig, $timeout, $websocket, $sce, proxySettings, $location, routeHistory, $q, $log, cheWorkspace) {
    this.cheAPI = cheAPI;
    this.$rootScope = $rootScope;
    this.lodash = lodash;
    this.$mdDialog = $mdDialog;
    this.$timeout = $timeout;
    this.$websocket = $websocket;
    this.userDashboardConfig = userDashboardConfig;
    this.$sce = $sce;
    this.proxySettings = proxySettings;
    this.$location = $location;
    this.routeHistory = routeHistory;
    this.$q = $q;
    this.$log = $log;
    this.cheWorkspace = cheWorkspace;

    this.ideParams = new Map();

    this.lastWorkspace = null;
    this.openedWorkspace = null;

    this.listeningChannels = [];
  }

  displayIDE() {
    this.$rootScope.showIDE = true;
  }

  restoreIDE() {
    this.$rootScope.restoringIDE = true;
    this.displayIDE();
  }

  hasIdeLink() {
    return this.$rootScope.ideIframeLink && (this.$rootScope.ideIframeLink !== null);
  }

  handleError(error) {
    this.$log.error(error);
  }

  startIde(workspace) {
    if (this.lastWorkspace) {
      this.cleanupChannels(this.lastWorkspace.id);
    }
    this.lastWorkspace = workspace;

    if (this.openedWorkspace && this.openedWorkspace.id === workspace.id) {
      this.openedWorkspace = null;
    }

    this.updateRecentWorkspace(workspace.id);

    let bus = this.cheAPI.getWebsocket().getBus(workspace.id);

    let startWorkspaceDefer = this.$q.defer();
    this.startWorkspace(bus, workspace).then(() => {
      // update list of workspaces
      // for new workspace to show in recent workspaces
      this.cheAPI.cheWorkspace.fetchWorkspaces();

      this.cheWorkspace.fetchStatusChange(workspace.id, 'RUNNING').then(() => {
        return this.cheWorkspace.fetchWorkspaceDetails(workspace.id);
      }).then(() => {
        startWorkspaceDefer.resolve();
      }, (error) => {
        this.handleError(error);
        startWorkspaceDefer.reject(error);
      });
      this.cheWorkspace.fetchStatusChange(workspace.id, 'ERROR').then((data) => {
        startWorkspaceDefer.reject(data);
      });
    }, (error) => {
      startWorkspaceDefer.reject(error);
    });

    return startWorkspaceDefer.promise.then(() => {
      if (this.lastWorkspace && workspace.id === this.lastWorkspace.id) {
        // Now that the container is started, wait for the extension server. For this, needs to get runtime details
        let websocketUrl = this.cheWorkspace.getWebsocketUrl(workspace.id);
        // try to connect
        this.websocketReconnect = 50;
        this.connectToExtensionServer(websocketUrl, workspace.id);
      } else {
        this.cleanupChannels(workspace.id);
      }
      return this.$q.resolve();
    }, (error) => {
      if (this.lastWorkspace && workspace.id === this.lastWorkspace.id) {
        this.cleanupChannels(workspace.id);
      }
      return this.$q.reject(error);
    });
  }

  startWorkspace(bus, data) {

    let startWorkspacePromise = this.cheAPI.getWorkspace().startWorkspace(data.id, data.config.defaultEnv);

    startWorkspacePromise.then((data) => {
      // get channels
      let environments = data.config.environments;
      let defaultEnvName = data.config.defaultEnv;
      let defaultEnvironment = this.lodash.find(environments, (environment) => {
        return environment.name === defaultEnvName;
      });

      let machineConfigsLinks = defaultEnvironment.machineConfigs[0].links;
      let findStatusLink = this.lodash.find(machineConfigsLinks, (machineConfigsLink) => {
        return machineConfigsLink.rel === 'get machine status channel';
      });

      let workspaceId = data.id;

      let agentChannel = 'workspace:' + data.id + ':ext-server:output';
      let statusChannel = findStatusLink ? findStatusLink.parameters[0].defaultValue : null;

      this.listeningChannels.push(statusChannel);
      // for now, display log of status channel in case of errors
      bus.subscribe(statusChannel, (message) => {
        if (message.eventType === 'DESTROYED' && message.workspaceId === data.id && !this.$rootScope.showIDE) {
          // need to show the error
          this.$mdDialog.show(
            this.$mdDialog.alert()
              .title('Unable to start workspace')
              .content('Unable to start workspace. It may be linked to OutOfMemory or the container has been destroyed')
              .ariaLabel('Workspace start')
              .ok('OK')
          );
        }
        if (message.eventType === 'ERROR' && message.workspaceId === data.id) {
          // need to show the error
          this.$mdDialog.show(
            this.$mdDialog.alert()
              .title('Error when starting workspace')
              .content('Unable to start workspace. Error when trying to start the workspace: ' + message.error)
              .ariaLabel('Workspace start')
              .ok('OK')
          );
        }
        this.$log.log('Status channel of workspaceID', workspaceId, message);
      });

      this.listeningChannels.push(agentChannel);
      bus.subscribe(agentChannel, (message) => {
        if (message.eventType === 'ERROR' && message.workspaceId === data.id) {
          // need to show the error
          this.$mdDialog.show(
            this.$mdDialog.alert()
              .title('Error when starting agent')
              .content('Unable to start workspace agent. Error when trying to start the workspace agent: ' + message.error)
              .ariaLabel('Workspace agent start')
              .ok('OK')
          );<commit_msg>CHE-1415: improve error message on workspace runtime killed<commit_after>/*
 * Copyright (c) 2015-2016 Codenvy, S.A.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Codenvy, S.A. - initial API and implementation
 */
'use strict';

/**
 * This class is handling the service for viewing the IDE
 * @author <NAME>
 */
class IdeSvc {

  /**
   * Default constructor that is using resource
   * @ngInject for Dependency injection
   */
  constructor(cheAPI, $rootScope, lodash, $mdDialog, userDashboardConfig, $timeout, $websocket, $sce, proxySettings, $location, routeHistory, $q, $log, cheWorkspace) {
    this.cheAPI = cheAPI;
    this.$rootScope = $rootScope;
    this.lodash = lodash;
    this.$mdDialog = $mdDialog;
    this.$timeout = $timeout;
    this.$websocket = $websocket;
    this.userDashboardConfig = userDashboardConfig;
    this.$sce = $sce;
    this.proxySettings = proxySettings;
    this.$location = $location;
    this.routeHistory = routeHistory;
    this.$q = $q;
    this.$log = $log;
    this.cheWorkspace = cheWorkspace;

    this.ideParams = new Map();

    this.lastWorkspace = null;
    this.openedWorkspace = null;

    this.listeningChannels = [];
  }

  displayIDE() {
    this.$rootScope.showIDE = true;
  }

  restoreIDE() {
    this.$rootScope.restoringIDE = true;
    this.displayIDE();
  }

  hasIdeLink() {
    return this.$rootScope.ideIframeLink && (this.$rootScope.ideIframeLink !== null);
  }

  handleError(error) {
    this.$log.error(error);
  }

  startIde(workspace) {
    if (this.lastWorkspace) {
      this.cleanupChannels(this.lastWorkspace.id);
    }
    this.lastWorkspace = workspace;

    if (this.openedWorkspace && this.openedWorkspace.id === workspace.id) {
      this.openedWorkspace = null;
    }

    this.updateRecentWorkspace(workspace.id);

    let bus = this.cheAPI.getWebsocket().getBus(workspace.id);

    let startWorkspaceDefer = this.$q.defer();
    this.startWorkspace(bus, workspace).then(() => {
      // update list of workspaces
      // for new workspace to show in recent workspaces
      this.cheAPI.cheWorkspace.fetchWorkspaces();

      this.cheWorkspace.fetchStatusChange(workspace.id, 'RUNNING').then(() => {
        return this.cheWorkspace.fetchWorkspaceDetails(workspace.id);
      }).then(() => {
        startWorkspaceDefer.resolve();
      }, (error) => {
        this.handleError(error);
        startWorkspaceDefer.reject(error);
      });
      this.cheWorkspace.fetchStatusChange(workspace.id, 'ERROR').then((data) => {
        startWorkspaceDefer.reject(data);
      });
    }, (error) => {
      startWorkspaceDefer.reject(error);
    });

    return startWorkspaceDefer.promise.then(() => {
      if (this.lastWorkspace && workspace.id === this.lastWorkspace.id) {
        // Now that the container is started, wait for the extension server. For this, needs to get runtime details
        let websocketUrl = this.cheWorkspace.getWebsocketUrl(workspace.id);
        // try to connect
        this.websocketReconnect = 50;
        this.connectToExtensionServer(websocketUrl, workspace.id);
      } else {
        this.cleanupChannels(workspace.id);
      }
      return this.$q.resolve();
    }, (error) => {
      if (this.lastWorkspace && workspace.id === this.lastWorkspace.id) {
        this.cleanupChannels(workspace.id);
      }
      return this.$q.reject(error);
    });
  }

  startWorkspace(bus, data) {

    let startWorkspacePromise = this.cheAPI.getWorkspace().startWorkspace(data.id, data.config.defaultEnv);

    startWorkspacePromise.then((data) => {
      // get channels
      let environments = data.config.environments;
      let defaultEnvName = data.config.defaultEnv;
      let defaultEnvironment = this.lodash.find(environments, (environment) => {
        return environment.name === defaultEnvName;
      });

      let machineConfigsLinks = defaultEnvironment.machineConfigs[0].links;
      let findStatusLink = this.lodash.find(machineConfigsLinks, (machineConfigsLink) => {
        return machineConfigsLink.rel === 'get machine status channel';
      });

      let workspaceId = data.id;

      let agentChannel = 'workspace:' + data.id + ':ext-server:output';
      let statusChannel = findStatusLink ? findStatusLink.parameters[0].defaultValue : null;

      this.listeningChannels.push(statusChannel);
      // for now, display log of status channel in case of errors
      bus.subscribe(statusChannel, (message) => {
        if (message.eventType === 'DESTROYED' && message.workspaceId === data.id && !this.$rootScope.showIDE) {
          // need to show the error
          this.$mdDialog.show(
            this.$mdDialog.alert()
              .title('Unable to start the workspace runtime')
              .content('Your workspace runtime is no longer available. It was either destroyed or ran out of memory.')
              .ariaLabel('Workspace start')
              .ok('OK')
          );
        }
        if (message.eventType === 'ERROR' && message.workspaceId === data.id) {
          // need to show the error
          this.$mdDialog.show(
            this.$mdDialog.alert()
              .title('Error when starting workspace')
              .content('Unable to start workspace. Error when trying to start the workspace: ' + message.error)
              .ariaLabel('Workspace start')
              .ok('OK')
          );
        }
        this.$log.log('Status channel of workspaceID', workspaceId, message);
      });

      this.listeningChannels.push(agentChannel);
      bus.subscribe(agentChannel, (message) => {
        if (message.eventType === 'ERROR' && message.workspaceId === data.id) {
          // need to show the error
          this.$mdDialog.show(
            this.$mdDialog.alert()
              .title('Error when starting agent')
              .content('Unable to start workspace agent. Error when trying to start the workspace agent: ' + message.error)
              .ariaLabel('Workspace agent start')
              .ok('OK')
          );
{'fraction_non_alphanumeric': 0.12514137986750687, 'fraction_numerical': 0.00290838584585555, 'mean_word_length': 2.7062874251497004, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '912995', 'n_tokens_mistral': 3554, 'n_tokens_neox': 3520, 'n_words': 807}