text: const temp = require('temp')
  const fs = require('fs')
  const path = require('path')
  const childProcess = require('child_process')
  const GitHubApi = require('github')
  const { getCurrentBranch } = require('./lib/utils.js')
  const request = require('request')
  const semver = require('semver')
  const rootPackageJson = require('../package.json')
  
  if (!process.env.ELECTRON_NPM_OTP) {
    console.error('Please set ELECTRON_NPM_OTP')
    process.exit(1)
  }
  
  const github = new GitHubApi({
    // debug: true,
    headers: { 'User-Agent': 'electron-npm-publisher' },
    followRedirects: false
  })
  
  let tempDir
  temp.track() // track and cleanup files at exit
  
  const files = [
    'cli.js',
    'index.js',
    'install.js',
    'package.json',
    'README.md',
    'LICENSE'
  ]
  
  const jsonFields = [
    'name',
    'version',
    'repository',
    'description',
    'license',
    'author',
    'keywords'
  ]
  
  let npmTag = ''
  
  new Promise((resolve, reject) => {
    temp.mkdir('electron-npm', (err, dirPath) => {
      if (err) {
        reject(err)
      } else {
        resolve(dirPath)
      }
    })
  })
    .then((dirPath) => {
      tempDir = dirPath
      // copy files from `/npm` to temp directory
      files.forEach((name) => {
        const noThirdSegment = name === 'README.md' || name === 'LICENSE'
        fs.writeFileSync(
          path.join(tempDir, name),
          fs.readFileSync(path.join(__dirname, '..', noThirdSegment ? '' : 'npm', name))
        )
      })
      // copy from root package.json to temp/package.json
      const packageJson = require(path.join(tempDir, 'package.json'))
      jsonFields.forEach((fieldName) => {
        packageJson[fieldName] = rootPackageJson[fieldName]
      })
      fs.writeFileSync(
        path.join(tempDir, 'package.json'),
        JSON.stringify(packageJson, null, 2)
      )
  
      return github.repos.getReleases({
        owner: 'electron',
        repo: rootPackageJson.version.indexOf('nightly') > 0 ? 'nightlies' : 'electron'
      })
    })
    .then((releases) => {
    // download electron.d.ts from release
      const release = releases.data.find(
        (release) => release.tag_name === `v${rootPackageJson.version}`
      )
      if (!release) {
        throw new Error(`cannot find release with tag v${rootPackageJson.version}`)
      }
      return release
    })
    .then((release) => {
      const tsdAsset = release.assets.find((asset) => asset.name === 'electron.d.ts')
      if (!tsdAsset) {
        throw new Error(`cannot find electron.d.ts from v${rootPackageJson.version} release assets`)
      }
      return new Promise((resolve, reject) => {
        request.get({
          url: tsdAsset.url,
          headers: {
            'accept': 'application/octet-stream',
            'user-agent': 'electron-npm-publisher'
          }
        }, (err, response, body) => {
          if (err || response.statusCode !== 200) {
            reject(err || new Error('Cannot download electron.d.ts'))
          } else {
            fs.writeFileSync(path.join(tempDir, 'electron.d.ts'), body)
            resolve(release)
          }
        })
      })
    })
    .then(async (release) => {
      const currentBranch = await getCurrentBranch()
  
      if (release.tag_name.indexOf('nightly') > 0) {
        if (currentBranch === 'master') {
          // Nightlies get published to their own module, so master nightlies should be tagged as latest
          npmTag = 'latest'
        } else {
          npmTag = `nightly-${currentBranch}`
        }
  
        const currentJson = JSON.parse(fs.readFileSync(path.join(tempDir, 'package.json'), 'utf8'))
        currentJson.name = 'electron-nightly'
        rootPackageJson.name = 'electron-nightly'
  
        fs.writeFileSync(
          path.join(tempDir, 'package.json'),
          JSON.stringify(currentJson, null, 2)
        )
      } else {
        if (currentBranch === 'master') {
          // This should never happen, master releases should be nightly releases
          // this is here just-in-case
          npmTag = 'master'
        } else if (!release.prerelease) {
          // Tag the release with a `2-0-x` style tag
          npmTag = currentBranch
        } else {
          // Tag the release with a `beta-3-0-x` style tag
          npmTag = `beta-${currentBranch}`
        }
      }
    })
    .then(() => childProcess.execSync('npm pack', { cwd: tempDir }))
    .then(() => {
    // test that the package can install electron prebuilt from github release
      const tarballPath = path.join(tempDir, `${rootPackageJson.name}-${rootPackageJson.version}.tgz`)
      return new Promise((resolve, reject) => {
        childProcess.execSync(`npm install ${tarballPath} --force --silent`, {
          env: Object.assign({}, process.env, { electron_config_cache: tempDir }),
          cwd: tempDir
        })
        resolve(tarballPath)
      })
    })
    .then((tarballPath) => childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag} --otp=${process.env.ELECTRON_NPM_OTP}`))
    .then(() => {
      const currentTags = JSON.parse(childProcess.execSync('npm show electron dist-tags --json').toString())
      const localVersion = rootPackageJson.version
      const parsedLocalVersion = semver.parse(localVersion)
      if (rootPackageJson.name === 'electron') {
        // We should only customly add dist tags for non-nightly releases where the package name is still
        // "electron"
        if (parsedLocalVersion.prerelease.length === 0 &&
              semver.gt(localVersion, currentTags.latest)) {
          childProcess.execSync(`npm dist-tag add electron@${localVersion} latest --otp=${process.env.ELECTRON_NPM_OTP}`)
        }
        if (parsedLocalVersion.prerelease[0] === 'beta' &&
              semver.gt(localVersion, currentTags.beta)) {
          childProcess.execSync(`npm dist-tag add electron@${localVersion} beta --otp=${process.env.ELECTRON_NPM_OTP}`)
        }
      }
    })
    .catch((err) => {
      console.error(`Error: ${err}`)
      process.exit(1)
    })
  