'use strict'

import Path from 'path'
import { spawn, spawnSync } from 'child_process'

const LOCAL_BIN_PATH = '/usr/local/bin'
export const CACHE_KEY = '__STEELBRAIN_CONSISTENT_ENV_V1'
export const assign = Object.assign || function (target, source) {
  for (const key in source) {
    if (source.hasOwnProperty(key)) {
      target[key] = source[key]
    }
  }
  return target
}

export function identifyEnvironment() {
  let environment
  try {
    environment = spawnSync(process.env.SHELL, ['-ic', 'env; exit']).stdout.toString().trim().split('\n')
  } catch (_) {
    throw new Error('Unable to determine environment')
  }
  return environment
}

export function identifyEnvironmentAsync() {
  return new Promise(function(resolve, reject) {
    const childProcess = spawn(process.env.SHELL, ['-ic', 'env; exit'])
    const stdout = []
    const timer = setTimeout(function() {
      childProcess.kill()
      reject()
    }, 2000)
    childProcess.stdout.on('data', function(chunk) {
      stdout.push(chunk)
    })
    childProcess.on('close', function() {
      clearTimeout(timer)
      resolve(stdout.join('').trim().split('\n'))
    })
    childProcess.on('error', function(error) {
      reject(error)
    })
  }).catch(function() {
    throw new Error('Unable to determine environment')
  })
}

export function parse(rawEnvironment) {
  const environment = {}
  for (const chunk of rawEnvironment) {
    const index = chunk.indexOf('=')
    if (index !== -1) {
      const key = chunk.slice(0, index).trim()
      const value = chunk.slice(index + 1).trim()
      environment[key] = value
    }
  }
  return environment
}

export function applySugar(environment) {
  let path = process.env.PATH ? process.env.PATH.split(':') : []
  if (environment.PATH) {
    for (const chunk of environment.PATH.split(':')) {
      if (chunk && path.indexOf(chunk) === -1) {
        path.push(chunk)
      }
    }
  }
  if (path.indexOf(LOCAL_BIN_PATH) === -1) {
    path = [LOCAL_BIN_PATH].concat(path)
  }
  if (!environment.USER) {
    if (process.env.USER) {
      environment.USER = process.env.USER
    } else if (environment.HOME) {
      environment.USER = Path.basename(environment.HOME)
    }
  }

  environment.PATH = path.join(':')
  environment.PWD = environment.OLDPWD = process.cwd()
  return environment
}

@@ -449,71 +449,116 @@
     
-environment = spawnSync(process.env.SHELL, %5B'-ic', 'env; exit'%5D
+const %7Bcommand, parameters, options%7D = getCommand()%0A    environment = spawnSync(command, parameters, options
 ).st
@@ -799,68 +799,113 @@
 nst 
-childProcess = spawn(process.env.SHELL, %5B'-ic', 'env; exit'%5D
+%7Bcommand, parameters, options%7D = getCommand()%0A    const childProcess = spawn(command, parameters, options
 )%0A  
@@ -2383,28 +2383,682 @@
 wd()%0A  return environment%0A%7D%0A
+%0Aexport function getCommand() %7B%0A  let command = process.env.SHELL%0A  let parameters%0A  let options = %7Btimeout: 3000, encoding: 'utf8'%7D%0A%0A  if (process.platform === 'darwin') %7B%0A    parameters = %5B'-ic', 'env;exit'%5D%0A  %7D else %7B%0A    // Linux%0A    const shell = Path.basename(process.env.SHELL)%0A    if (shell === 'bash') %7B%0A      parameters = %5B'-c', 'source ~/.bashrc;env;exit'%5D%0A    %7D else if (shell === 'zsh') %7B%0A      parameters = %5B'-c', 'source ~/.zshrc;env;exit'%5D%0A    %7D else if (shell === 'fish') %7B%0A      parameters = %5B'-c', '. ~/.config/fish/config.fish;env;exit'%5D%0A    %7D else throw new Error('Unknown shell type')%0A  %7D%0A%0A  return %7Bcommand, parameters, options%7D%0A%7D%0A

Add and use getCommand helper