/**
 * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
 * SPDX-License-Identifier: MIT
 */

const fs = require("fs");
const path = require("path");
const ig = require("ignore")();

const ignorePaths = [
  '.next',
  'doc_build',
  'apps/docs/components/free-examples',
  'apps/docs/components/fixed-examples',
]


const ignoreFile = fs.readFileSync(path.join(__dirname, "../../../.gitignore"), {
  encoding: "utf-8",
});
ig.add(ignoreFile);
// ignore custom paths
ig.add(ignorePaths);

const src = path.resolve(__dirname, '../../../');

const header = ` Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
 SPDX-License-Identifier: MIT`;

const bashHeaders = [`#!/usr/bin/env`, `#!/bin/sh`];
const rushPreHeader = `// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.`;

/**
* Add License Header to all files in the folder
* @param {string} targetDir - target folder path (absolute path)
* @param {string} licenseContent - License content to be added (plain text)
* @param {object} options - configuration items
* @param {string[]} [options.includeExts] - file extensions to be processed (such as ['.js', '.ts']), all text files are processed by default
* @param {string[]} [options.excludeDirs] - directories to be excluded (such as ['node_modules', 'dist'])
* @param {string} [options.commentLinePrefix] - comment prefix (such as '// ' or '/* '), comment format is not added by default
* @param {boolean} [options.force] - whether to force overwrite (re-add even if there is already a license), default false
*/
function addLicenseHeader(targetDir, licenseContent, options = {}) {
  const {
    includeExts = [".js", ".ts", ".mjs", ".cjs", ".html", ".css", ".scss"],
    commentLinePrefix = "// ", // default by js
    commentPrefix,
    commentSuffix,
    force = false,
  } = options;

  const licensedText =
    (commentPrefix ? commentPrefix + "\n" : "") +
    licenseContent
      .split("\n")
      .map((line) => commentLinePrefix + line)
      .join("\n") +
    (commentSuffix ? "\n" + commentSuffix : "") +
    "\n\n";

  function traverseDir(currentDir) {
    const entries = fs.readdirSync(currentDir, { withFileTypes: true });

    for (const entry of entries) {
      const fullPath = path.join(currentDir, entry.name);

      if (
        ig.ignores(path.relative(targetDir, fullPath))
      ) {
        continue;
      }

      if (entry.isDirectory()) {
        traverseDir(fullPath);
      } else {
        processFile(fullPath);
      }
    }
  }

  function processFile(filePath) {
    const ext = path.extname(filePath).toLowerCase();
    if (includeExts.length > 0 && !includeExts.includes(ext)) {
      return;
    }

    try {
      const originalContent = fs.readFileSync(filePath, "utf8");

      // Check if the license already exists (simple match at the beginning)
      if (!force && (originalContent.startsWith(licensedText.trim()) || bashHeaders.some(_header => originalContent.startsWith(_header.trim())) || originalContent.startsWith(rushPreHeader.trim()))) {
        return;
      }

      let newContent = originalContent;

      const shebangMatch = originalContent.match(/^#!.*\n/);
      if (shebangMatch) {
        newContent =
          shebangMatch[0] +
          licensedText +
          originalContent.replace(shebangMatch[0], "");
      } else {
        newContent = licensedText + originalContent;
      }

      fs.writeFileSync(filePath, newContent, "utf8");
      console.log(`[Success] License added: ${filePath}, please manually upload the locally modified file`);
    } catch (err) {
      console.error(`[ERROR] Failed to process file ${filePath}:`, err.message);
    }
  }

  if (fs.existsSync(targetDir) && fs.statSync(targetDir).isDirectory()) {
    traverseDir(targetDir);
    console.log("License Header add successfully");
  } else {
    console.error("Error: The destination path is not a valid folder");
  }
}

addLicenseHeader(
    src,
    header,
    {
        includeExts: ['.js', '.ts', '.tsx', '.jsx', '.mjs', '.cjs', '.scss', '.less', '.prisma', '.styl', '.css'],
        commentPrefix: '/**',
        commentLinePrefix: ' *',
        commentSuffix: ' */',
        force: false
    }
);

addLicenseHeader(
    src,
    header,
    {
        includeExts: ['.sh'],
        commentLinePrefix: '# ',
        force: false
    }
);
