11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst procLog = require('proc-log')
41cb0ef41Sopenharmony_ciconst { format } = require('util')
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci// helper to emit log messages with a predefined prefix
71cb0ef41Sopenharmony_ciconst logLevels = Object.keys(procLog).filter((k) => typeof procLog[k] === 'function')
81cb0ef41Sopenharmony_ciconst withPrefix = (prefix) => logLevels.reduce((acc, level) => {
91cb0ef41Sopenharmony_ci  acc[level] = (...args) => procLog[level](prefix, ...args)
101cb0ef41Sopenharmony_ci  return acc
111cb0ef41Sopenharmony_ci}, {})
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci// very basic ansi color generator
141cb0ef41Sopenharmony_ciconst COLORS = {
151cb0ef41Sopenharmony_ci  wrap: (str, colors) => {
161cb0ef41Sopenharmony_ci    const codes = colors.filter(c => typeof c === 'number')
171cb0ef41Sopenharmony_ci    return `\x1b[${codes.join(';')}m${str}\x1b[0m`
181cb0ef41Sopenharmony_ci  },
191cb0ef41Sopenharmony_ci  inverse: 7,
201cb0ef41Sopenharmony_ci  fg: {
211cb0ef41Sopenharmony_ci    black: 30,
221cb0ef41Sopenharmony_ci    red: 31,
231cb0ef41Sopenharmony_ci    green: 32,
241cb0ef41Sopenharmony_ci    yellow: 33,
251cb0ef41Sopenharmony_ci    blue: 34,
261cb0ef41Sopenharmony_ci    magenta: 35,
271cb0ef41Sopenharmony_ci    cyan: 36,
281cb0ef41Sopenharmony_ci    white: 37
291cb0ef41Sopenharmony_ci  },
301cb0ef41Sopenharmony_ci  bg: {
311cb0ef41Sopenharmony_ci    black: 40,
321cb0ef41Sopenharmony_ci    red: 41,
331cb0ef41Sopenharmony_ci    green: 42,
341cb0ef41Sopenharmony_ci    yellow: 43,
351cb0ef41Sopenharmony_ci    blue: 44,
361cb0ef41Sopenharmony_ci    magenta: 45,
371cb0ef41Sopenharmony_ci    cyan: 46,
381cb0ef41Sopenharmony_ci    white: 47
391cb0ef41Sopenharmony_ci  }
401cb0ef41Sopenharmony_ci}
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ciclass Logger {
431cb0ef41Sopenharmony_ci  #buffer = []
441cb0ef41Sopenharmony_ci  #paused = null
451cb0ef41Sopenharmony_ci  #level = null
461cb0ef41Sopenharmony_ci  #stream = null
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  // ordered from loudest to quietest
491cb0ef41Sopenharmony_ci  #levels = [{
501cb0ef41Sopenharmony_ci    id: 'silly',
511cb0ef41Sopenharmony_ci    display: 'sill',
521cb0ef41Sopenharmony_ci    style: { inverse: true }
531cb0ef41Sopenharmony_ci  }, {
541cb0ef41Sopenharmony_ci    id: 'verbose',
551cb0ef41Sopenharmony_ci    display: 'verb',
561cb0ef41Sopenharmony_ci    style: { fg: 'cyan', bg: 'black' }
571cb0ef41Sopenharmony_ci  }, {
581cb0ef41Sopenharmony_ci    id: 'info',
591cb0ef41Sopenharmony_ci    style: { fg: 'green' }
601cb0ef41Sopenharmony_ci  }, {
611cb0ef41Sopenharmony_ci    id: 'http',
621cb0ef41Sopenharmony_ci    style: { fg: 'green', bg: 'black' }
631cb0ef41Sopenharmony_ci  }, {
641cb0ef41Sopenharmony_ci    id: 'notice',
651cb0ef41Sopenharmony_ci    style: { fg: 'cyan', bg: 'black' }
661cb0ef41Sopenharmony_ci  }, {
671cb0ef41Sopenharmony_ci    id: 'warn',
681cb0ef41Sopenharmony_ci    display: 'WARN',
691cb0ef41Sopenharmony_ci    style: { fg: 'black', bg: 'yellow' }
701cb0ef41Sopenharmony_ci  }, {
711cb0ef41Sopenharmony_ci    id: 'error',
721cb0ef41Sopenharmony_ci    display: 'ERR!',
731cb0ef41Sopenharmony_ci    style: { fg: 'red', bg: 'black' }
741cb0ef41Sopenharmony_ci  }]
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  constructor (stream) {
771cb0ef41Sopenharmony_ci    process.on('log', (...args) => this.#onLog(...args))
781cb0ef41Sopenharmony_ci    this.#levels = new Map(this.#levels.map((level, index) => [level.id, { ...level, index }]))
791cb0ef41Sopenharmony_ci    this.level = 'info'
801cb0ef41Sopenharmony_ci    this.stream = stream
811cb0ef41Sopenharmony_ci    procLog.pause()
821cb0ef41Sopenharmony_ci  }
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  get stream () {
851cb0ef41Sopenharmony_ci    return this.#stream
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  set stream (stream) {
891cb0ef41Sopenharmony_ci    this.#stream = stream
901cb0ef41Sopenharmony_ci  }
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  get level () {
931cb0ef41Sopenharmony_ci    return this.#levels.get(this.#level) ?? null
941cb0ef41Sopenharmony_ci  }
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  set level (level) {
971cb0ef41Sopenharmony_ci    this.#level = this.#levels.get(level)?.id ?? null
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  isVisible (level) {
1011cb0ef41Sopenharmony_ci    return this.level?.index <= this.#levels.get(level)?.index ?? -1
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  #onLog (...args) {
1051cb0ef41Sopenharmony_ci    const [level] = args
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci    if (level === 'pause') {
1081cb0ef41Sopenharmony_ci      this.#paused = true
1091cb0ef41Sopenharmony_ci      return
1101cb0ef41Sopenharmony_ci    }
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci    if (level === 'resume') {
1131cb0ef41Sopenharmony_ci      this.#paused = false
1141cb0ef41Sopenharmony_ci      this.#buffer.forEach((b) => this.#log(...b))
1151cb0ef41Sopenharmony_ci      this.#buffer.length = 0
1161cb0ef41Sopenharmony_ci      return
1171cb0ef41Sopenharmony_ci    }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci    if (this.#paused) {
1201cb0ef41Sopenharmony_ci      this.#buffer.push(args)
1211cb0ef41Sopenharmony_ci      return
1221cb0ef41Sopenharmony_ci    }
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci    this.#log(...args)
1251cb0ef41Sopenharmony_ci  }
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  #color (str, { fg, bg, inverse }) {
1281cb0ef41Sopenharmony_ci    if (!this.#stream?.isTTY) {
1291cb0ef41Sopenharmony_ci      return str
1301cb0ef41Sopenharmony_ci    }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci    return COLORS.wrap(str, [
1331cb0ef41Sopenharmony_ci      COLORS.fg[fg],
1341cb0ef41Sopenharmony_ci      COLORS.bg[bg],
1351cb0ef41Sopenharmony_ci      inverse && COLORS.inverse
1361cb0ef41Sopenharmony_ci    ])
1371cb0ef41Sopenharmony_ci  }
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci  #log (levelId, msgPrefix, ...args) {
1401cb0ef41Sopenharmony_ci    if (!this.isVisible(levelId) || typeof this.#stream?.write !== 'function') {
1411cb0ef41Sopenharmony_ci      return
1421cb0ef41Sopenharmony_ci    }
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci    const level = this.#levels.get(levelId)
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci    const prefixParts = [
1471cb0ef41Sopenharmony_ci      this.#color('gyp', { fg: 'white', bg: 'black' }),
1481cb0ef41Sopenharmony_ci      this.#color(level.display ?? level.id, level.style)
1491cb0ef41Sopenharmony_ci    ]
1501cb0ef41Sopenharmony_ci    if (msgPrefix) {
1511cb0ef41Sopenharmony_ci      prefixParts.push(this.#color(msgPrefix, { fg: 'magenta' }))
1521cb0ef41Sopenharmony_ci    }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci    const prefix = prefixParts.join(' ').trim() + ' '
1551cb0ef41Sopenharmony_ci    const lines = format(...args).split(/\r?\n/).map(l => prefix + l.trim())
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci    this.#stream.write(lines.join('\n') + '\n')
1581cb0ef41Sopenharmony_ci  }
1591cb0ef41Sopenharmony_ci}
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci// used to suppress logs in tests
1621cb0ef41Sopenharmony_ciconst NULL_LOGGER = !!process.env.NODE_GYP_NULL_LOGGER
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_cimodule.exports = {
1651cb0ef41Sopenharmony_ci  logger: new Logger(NULL_LOGGER ? null : process.stderr),
1661cb0ef41Sopenharmony_ci  stdout: NULL_LOGGER ? () => {} : (...args) => console.log(...args),
1671cb0ef41Sopenharmony_ci  withPrefix,
1681cb0ef41Sopenharmony_ci  ...procLog
1691cb0ef41Sopenharmony_ci}
170