import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const SKIP_DIRS = new Set(["node_modules", ".git", ".well-known", "cgi-bin"]);
const EXT = new Set([".js", ".mjs", ".cjs", ".css", ".html", ".php", ".bat"]);

function walk(dir, out = []) {
  for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
    if (SKIP_DIRS.has(ent.name)) continue;
    const p = path.join(dir, ent.name);
    if (ent.isDirectory()) walk(p, out);
    else if (EXT.has(path.extname(ent.name).toLowerCase())) out.push(p);
  }
  return out;
}

function protectSingleQuotedStrings(s) {
  const slots = [];
  let out = "";
  let i = 0;
  const n = s.length;
  while (i < n) {
    const ch = s[i];
    if (ch === "'") {
      const start = i;
      i++;
      while (i < n) {
        if (s[i] === "\\" && i + 1 < n) {
          i += 2;
          continue;
        }
        if (s[i] === "'") {
          i++;
          break;
        }
        i++;
      }
      slots.push(s.slice(start, i));
      out += `\x00S${slots.length - 1}\x00`;
      continue;
    }
    out += ch;
    i++;
  }
  return { text: out, slots };
}

function restoreSlots(text, slots) {
  let out = text;
  for (let i = 0; i < slots.length; i++) {
    out = out.split(`\x00S${i}\x00`).join(slots[i]);
  }
  return out;
}

function stripHtmlComments(s) {
  return s.replace(/<!--[\s\S]*?-->/g, "");
}

function stripCssComments(s) {
  return s.replace(/\/\*[\s\S]*?\*\//g, "");
}

function isCommentOnlyLine(trimmed) {
  if (!trimmed) return false;
  if (/^\/\/./.test(trimmed)) return true;
  if (/^#/.test(trimmed)) return true;
  if (/^\/\*[\s\S]*\*\/$/.test(trimmed)) return true;
  if (/^\*(\s|$)/.test(trimmed)) return true;
  if (/^\/\*\*/.test(trimmed)) return true;
  return false;
}

function cleanJsLike(src) {
  let text = src.replace(/\r\n/g, "\n");
  text = text.replace(/^[ \t]*\/\*[\s\S]*?^[ \t]*\*\/[ \t]*$/gm, "");
  const lines = text.split("\n");
  const kept = [];
  for (const line of lines) {
    const trimmed = line.trim();
    if (isCommentOnlyLine(trimmed)) continue;
    kept.push(line.replace(/[ \t]+$/, ""));
  }
  return kept.join("\n").replace(/\n{3,}/g, "\n\n");
}

function cleanPhp(src) {
  const { text, slots } = protectSingleQuotedStrings(src.replace(/\r\n/g, "\n"));
  let bare = text.replace(/^[ \t]*\/\*[\s\S]*?^[ \t]*\*\/[ \t]*$/gm, "");
  bare = bare.replace(/\/\*[\s\S]*?\*\//g, "");
  bare = bare.replace(/^\s*\/\/.*$/gm, "");
  bare = bare.replace(/^\s*#.*$/gm, "");
  bare = restoreSlots(bare, slots);
  return bare.replace(/\n{3,}/g, "\n\n");
}

function cleanHtml(src) {
  let r = stripHtmlComments(src);
  r = r.replace(/<style([^>]*)>([\s\S]*?)<\/style>/gi, (_, attrs, css) => `<style${attrs}>${stripCssComments(css)}</style>`);
  return r;
}

function cleanBat(src) {
  return src.replace(/^\s*rem\b.*$/gim, "").replace(/^\s*::.*$/gim, "");
}

function cleanFile(filePath) {
  const ext = path.extname(filePath).toLowerCase();
  const original = fs.readFileSync(filePath, "utf8");
  let src = original;

  if (ext === ".html") src = cleanHtml(src);
  else if (ext === ".css") src = stripCssComments(src);
  else if (ext === ".js" || ext === ".mjs" || ext === ".cjs") src = cleanJsLike(src);
  else if (ext === ".php") src = cleanPhp(src);
  else if (ext === ".bat") src = cleanBat(src);

  if (src !== original) {
    fs.writeFileSync(filePath, src, "utf8");
    return true;
  }
  return false;
}

const selfPath = path.join(ROOT, "scripts", "strip-all-comments.mjs");
const skip = new Set([
  selfPath,
  path.join(ROOT, "scripts", "test-strip.mjs"),
  path.join(ROOT, "scripts", "find-comment-slots.mjs"),
  path.join(ROOT, "scripts", "force-strip-remaining.mjs"),
  path.join(ROOT, "scripts", "debug-quote.mjs"),
]);

let changed = 0;
for (const f of walk(ROOT).filter((p) => !skip.has(p))) {
  if (cleanFile(f)) {
    changed++;
    console.log(path.relative(ROOT, f));
  }
}
console.log(`\n${changed} dosya güncellendi.`);
