import fs from "node:fs";
import path from "node:path";
import {pipeline} from "node:stream/promises";
import {Readable} from "node:stream";

function safeKey(key) {
  const normalized = path.posix.normalize(String(key || "")).replace(/^\.\.\//g, "");
  if (!normalized || normalized.startsWith("/") || normalized.includes("../")) {
    throw new Error("invalid_bundle_storage_key");
  }
  return normalized;
}

export function coreStaticStorage(options = {}) {
  const rootDir = path.resolve(
    options.rootDir ||
      process.env.DANOGO_MOBILE_BUNDLE_DIR ||
      "../ota-server/data/bundles",
  );
  const publicBaseUrl = String(
    options.publicBaseUrl ||
      process.env.DANOGO_MOBILE_BUNDLE_PUBLIC_BASE ||
      "https://danogo.theappmasters.com/mobile-bundles",
  ).replace(/\/$/, "");

  fs.mkdirSync(rootDir, {recursive: true});

  return {
    name: "danogo-core-static",
    supportedProtocol: "https",
    profiles: {
      node: {
        async upload(key, filePath) {
          const clean = safeKey(key);
          const target = path.resolve(rootDir, clean);
          if (!target.startsWith(rootDir + path.sep)) {
            throw new Error("bundle_storage_escape_rejected");
          }
          fs.mkdirSync(path.dirname(target), {recursive: true});
          fs.copyFileSync(filePath, target);
          return {
            storageUri: `${publicBaseUrl}/${clean.split(path.sep).join("/")}`,
          };
        },

        async exists(storageUri) {
          const url = new URL(storageUri);
          const base = new URL(publicBaseUrl + "/");
          if (url.origin !== base.origin || !url.pathname.startsWith(base.pathname)) {
            return false;
          }
          const rel = decodeURIComponent(url.pathname.slice(base.pathname.length));
          const target = path.resolve(rootDir, safeKey(rel));
          return target.startsWith(rootDir + path.sep) && fs.existsSync(target);
        },

        async delete(storageUri) {
          const url = new URL(storageUri);
          const base = new URL(publicBaseUrl + "/");
          if (url.origin !== base.origin || !url.pathname.startsWith(base.pathname)) {
            throw new Error("bundle_storage_uri_not_owned");
          }
          const rel = decodeURIComponent(url.pathname.slice(base.pathname.length));
          const target = path.resolve(rootDir, safeKey(rel));
          if (!target.startsWith(rootDir + path.sep)) {
            throw new Error("bundle_storage_escape_rejected");
          }
          fs.rmSync(target, {force: true});
        },

        async downloadFile(storageUri, filePath) {
          const response = await fetch(storageUri);
          if (!response.ok || !response.body) {
            throw new Error(`bundle_download_failed_${response.status}`);
          }
          fs.mkdirSync(path.dirname(path.resolve(filePath)), {recursive: true});
          await pipeline(
            Readable.fromWeb(response.body),
            fs.createWriteStream(filePath),
          );
        },
      },
    },
  };
}
