<commit_before>'use babel';

/**
 * Copyright (C) 2016 <NAME>. All rights reserved.
 *
 * This source file is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

import fs from 'fs-extra';
import child_process from 'child_process';
import {https} from 'follow-redirects';
import temp from 'temp';
import path from 'path';
import shell from 'shell';
import tarball from 'tarball-extract';
import semver from 'semver';
import {useBuiltinPlatformIO, getPythonExecutable, findFileByName, runAtomCommand} from '../utils';
import {InstallPlatformIOView} from './view';
import {CACHE_DIR, DEPENDENCIES, ENV_DIR, ENV_BIN_DIR, STALE_DEPENDENCIES} from '../config';

const STATE_KEY = 'platformio-ide:install-state';
const PROGRESS_STEPS = 8;

// Install PlatformIO
export function command() {
  const chain = Promise.resolve()
    .then(initializeState)
    .then(ensureThatCacheDirectoryExists)
    .then(checkIfVirtualenvShouldBeCreated)
    .then(checkIfPackageManagmentIsNecessary)
    .then(initializeView)
    .then(wrap(ensurePythonIsAvailable))

    .then(wrap(installPlatformIO))

    .then(wrap(installDependenciesFirstTime))
    .then(wrap(uninstallStaleDependencies))
    .then(wrap(installNewDependencies))
    .then(wrap(upgradeOutdatedDependencies))
    .then(wrap(activateInactiveDependencies))
    .then(wrap(adjustToolbarPosition))

    .then(notifyUser)

    .catch((err) => {
      return cleanup()
        .then(() => console.error(err));
    })

    .then(cleanupIfCanceled)
    .then(destroyViewAndSaveState);

  return chain;
}

export function reinstallPlatformIO(useDevelop) {
  const executable = path.join(ENV_BIN_DIR, 'pip');
  const notifocation = atom.notifications.addInfo('PlaformIO reinstalling initiated.',{
    dismissable: true,
    detail: 'Please wait.',
  });
  return Promise.resolve()
    .then(() => {
      return new Promise((resolve) => {
        // try to uninstall previous PlatformIO if exists
        const child = child_process.spawn(executable, ['uninstall', '-y' ,'platformio']);
        child.on('close', () => resolve());
      });
    })
    .then(() => {
      return new Promise((resolve, reject) => {
        let args = ['install'];
        if (useDevelop) {
          args.push('https://github.com/platformio/platformio/archive/develop.zip');
        } else {
          args.push('platformio');
        }

        let stderr = '';
        const child = child_process.spawn(executable, args);
        child.stderr.on('data', chunk => stderr += chunk);
        child.on('close', (code) => {
          if (0 !== code) {
            let title = 'PlaftormIO: Failed to install PlatformIO!';
            atom.notifications.addError(title, {detail: stderr, dismissable: true});
            console.error(title);
            console.error(stderr);
            reject();
          }
          resolve();
        });
      });
    })
    .then(() => notifocation.dismiss())
    .catch((err) => {
      notifocation.dismiss();
      throw err;
    });
}


// Tasks below are installation steps. Each task must accept a state as an
// argument and eventually return a modified state (directly or via promise).

function initializeState() {
  return new Promise((resolve) => {
    // Retrieve the state object from localStorage
    let state;
    try {
      state = JSON.parse(localStorage.getItem(STATE_KEY));
      if (!(state instanceof Object)) {
        throw new TypeError('State must be an object.');
      }
      if (state) {
        state.restored = true;
      }
    } catch(err) {<commit_msg>Don't bother user with error when state parsing failed<commit_after>'use babel';

/**
 * Copyright (C) 2016 <NAME>. All rights reserved.
 *
 * This source file is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

import fs from 'fs-extra';
import child_process from 'child_process';
import {https} from 'follow-redirects';
import temp from 'temp';
import path from 'path';
import shell from 'shell';
import tarball from 'tarball-extract';
import semver from 'semver';
import {useBuiltinPlatformIO, getPythonExecutable, findFileByName, runAtomCommand} from '../utils';
import {InstallPlatformIOView} from './view';
import {CACHE_DIR, DEPENDENCIES, ENV_DIR, ENV_BIN_DIR, STALE_DEPENDENCIES} from '../config';

const STATE_KEY = 'platformio-ide:install-state';
const PROGRESS_STEPS = 8;

// Install PlatformIO
export function command() {
  const chain = Promise.resolve()
    .then(initializeState)
    .then(ensureThatCacheDirectoryExists)
    .then(checkIfVirtualenvShouldBeCreated)
    .then(checkIfPackageManagmentIsNecessary)
    .then(initializeView)
    .then(wrap(ensurePythonIsAvailable))

    .then(wrap(installPlatformIO))

    .then(wrap(installDependenciesFirstTime))
    .then(wrap(uninstallStaleDependencies))
    .then(wrap(installNewDependencies))
    .then(wrap(upgradeOutdatedDependencies))
    .then(wrap(activateInactiveDependencies))
    .then(wrap(adjustToolbarPosition))

    .then(notifyUser)

    .catch((err) => {
      return cleanup()
        .then(() => console.error(err));
    })

    .then(cleanupIfCanceled)
    .then(destroyViewAndSaveState);

  return chain;
}

export function reinstallPlatformIO(useDevelop) {
  const executable = path.join(ENV_BIN_DIR, 'pip');
  const notifocation = atom.notifications.addInfo('PlaformIO reinstalling initiated.',{
    dismissable: true,
    detail: 'Please wait.',
  });
  return Promise.resolve()
    .then(() => {
      return new Promise((resolve) => {
        // try to uninstall previous PlatformIO if exists
        const child = child_process.spawn(executable, ['uninstall', '-y' ,'platformio']);
        child.on('close', () => resolve());
      });
    })
    .then(() => {
      return new Promise((resolve, reject) => {
        let args = ['install'];
        if (useDevelop) {
          args.push('https://github.com/platformio/platformio/archive/develop.zip');
        } else {
          args.push('platformio');
        }

        let stderr = '';
        const child = child_process.spawn(executable, args);
        child.stderr.on('data', chunk => stderr += chunk);
        child.on('close', (code) => {
          if (0 !== code) {
            let title = 'PlaftormIO: Failed to install PlatformIO!';
            atom.notifications.addError(title, {detail: stderr, dismissable: true});
            console.error(title);
            console.error(stderr);
            reject();
          }
          resolve();
        });
      });
    })
    .then(() => notifocation.dismiss())
    .catch((err) => {
      notifocation.dismiss();
      throw err;
    });
}


// Tasks below are installation steps. Each task must accept a state as an
// argument and eventually return a modified state (directly or via promise).

function initializeState() {
  return new Promise((resolve) => {
    // Retrieve the state object from localStorage
    let state;
    try {
      state = JSON.parse(localStorage.getItem(STATE_KEY));
      if (state instanceof Object) {
        state.restored = true;
      } else {
        state = {};
      }
    } catch(err) {
{'fraction_non_alphanumeric': 0.12080048514251061, 'fraction_numerical': 0.004366282595512432, 'mean_word_length': 3.1751898734177213, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 29, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4855252', 'n_tokens_mistral': 2373, 'n_tokens_neox': 2291, 'n_words': 689}