// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

'use strict'

const fs = require('node:fs')
const path = require('node:path')
const { spawn } = require('node:child_process')
const PROJECT_ROOT = path.normalize(path.join(__dirname, '../../../..'))
const WORKSPACE_FILE = path.join(PROJECT_ROOT, 'WORKSPACE')

function isDevMode() {
  return fs.existsSync(WORKSPACE_FILE)
}

function checkIsDevMode() {
  if (!isDevMode()) {
    throw Error('Cannot execute build; not running in dev mode')
  }
}

/**
 * Targets that have been previously built.
 * @type {!Object}
 */
let builtTargets = {}

/**
 * @param {!Array.<string>} targets The targets to build.
 * @throws {Error} If not running in dev mode.
 * @constructor
 */
const Build = function (targets) {
  checkIsDevMode()
  this.targets_ = targets
}

/** @private {boolean} */
Build.prototype.cacheResults_ = false

/**
 * Configures this build to only execute if it has not previously been
 * run during the life of the current process.
 * @return {!Build} A self reference.
 */
Build.prototype.onlyOnce = function () {
  this.cacheResults_ = true
  return this
}

/**
 * Executes the build.
 * @return {!Promise} A promise that will be resolved when
 *     the build has completed.
 * @throws {Error} If no targets were specified.
 */
Build.prototype.go = function () {
  let targets = this.targets_
  if (!targets.length) {
    throw Error('No targets specified')
  }

  // Filter out cached results.
  if (this.cacheResults_) {
    targets = targets.filter(function (target) {
      return !Object.prototype.hasOwnProperty.call(builtTargets, target)
    })

    if (!targets.length) {
      return Promise.resolve()
    }
  }

  console.log('\nBuilding', targets.join(' '), '...')

  let cmd,
    args = targets
  if (process.platform === 'win32') {
    cmd = 'cmd.exe'
    args.unshift('/c', path.join(PROJECT_ROOT, 'go.bat'))
  } else {
    cmd = path.join(PROJECT_ROOT, 'go')
  }

  return new Promise((resolve, reject) => {
    spawn(cmd, args, {
      cwd: PROJECT_ROOT,
      env: process.env,
      stdio: ['ignore', process.stdout, process.stderr],
    }).on('exit', function (code, signal) {
      if (code === 0) {
        targets.forEach(function (target) {
          builtTargets[target] = 1
        })
        return resolve()
      }

      let msg = 'Unable to build artifacts'
      if (code) {
        // May be null.
        msg += '; code=' + code
      }
      if (signal) {
        msg += '; signal=' + signal
      }

      reject(Error(msg))
    })
  })
}

// PUBLIC API

exports.isDevMode = isDevMode

/**
 * Creates a build of the listed targets.
 * @param {...string} var_args The targets to build.
 * @return {!Build} The new build.
 * @throws {Error} If not running in dev mode.
 */
exports.of = function (_) {
  let targets = Array.prototype.slice.call(arguments, 0)
  return new Build(targets)
}

/**
 * @return {string} Absolute path of the project's root directory.
 * @throws {Error} If not running in dev mode.
 */
exports.projectRoot = function () {
  return PROJECT_ROOT
}
