const fs = require('fs')
const path = require('path')
const { getConfig } = require('./config')

/**
 * Absolute path to the consumer site's cmsDependencies module, or null if unknown.
 * Resolution: --deps-file, else sitePath + cmsDependenciesFile from config.
 *
 * @param {object} [opts]
 * @param {string} [opts.depsFile] - Explicit file path
 * @param {string} [opts.sitePath] - Site root (config default when omitted)
 * @param {object} [opts.config] - Override merged config (defaults to getConfig())
 */
function resolveCmsDependenciesFilePath(opts = {}) {
  const config = opts.config !== undefined ? opts.config : getConfig()
  if (opts.depsFile) {
    return path.resolve(opts.depsFile)
  }
  const sitePath = opts.sitePath || config.sitePath
  const depsName = config.cmsDependenciesFile || 'src/cmsDependencies.ts'
  if (!sitePath) {
    return null
  }
  return path.resolve(sitePath, depsName)
}

/**
 * Walk up from a file (or its directory) until a directory containing `package.json` is found.
 * Used to infer the consumer site root when `sitePath` is unset (e.g. `bild template` run from
 * a repo without `~/.bild.json` sitePath) so the Components barrel can still be found.
 *
 * @param {string} absFileOrDir
 * @returns {string|null}
 */
function inferSitePathFromFile(absFileOrDir) {
  let dir = path.resolve(absFileOrDir)
  if (fs.existsSync(dir) && fs.statSync(dir).isFile()) {
    dir = path.dirname(dir)
  }
  for (let i = 0; i < 20; i += 1) {
    if (fs.existsSync(path.join(dir, 'package.json'))) {
      return dir
    }
    const parent = path.dirname(dir)
    if (parent === dir) break
    dir = parent
  }
  return null
}

module.exports = {
  resolveCmsDependenciesFilePath,
  inferSitePathFromFile,
}
