// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { dirname } from "jsr:/@std/path@^0.224.0/dirname";
import { ensureDir, ensureDirSync } from "./ensure_dir.ts";
import { getFileInfoType } from "./_get_file_info_type.ts";
import { toPathString } from "./_to_path_string.ts";

/**
 * Asynchronously ensures that the file exists. If the file that is requested to
 * be created is in directories that do not exist, these directories are created.
 * If the file already exists, it is not modified.
 *
 * Requires the `--allow-read` and `--allow-write` flag.
 *
 * @param filePath The path of the file to ensure, as a string or URL.
 * @returns A void promise that resolves once the file exists.
 *
 * @example
 * ```ts
 * import { ensureFile } from "@std/fs/ensure-file";
 *
 * await ensureFile("./folder/targetFile.dat");
 * ```
 */
export async function ensureFile(filePath: string | URL): Promise<void> {
  try {
    // if file exists
    const stat = await Deno.lstat(filePath);
    if (!stat.isFile) {
      throw new Error(
        `Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`,
      );
    }
  } catch (err) {
    // if file not exists
    if (err instanceof Deno.errors.NotFound) {
      // ensure dir exists
      await ensureDir(dirname(toPathString(filePath)));
      // create file
      await Deno.writeFile(filePath, new Uint8Array());
      return;
    }

    throw err;
  }
}

/**
 * Synchronously ensures that the file exists. If the file that is requested to
 * be created is in directories that do not exist, these directories are created.
 * If the file already exists, it is not modified.
 *
 * Requires the `--allow-read` and `--allow-write` flag.
 *
 * @param filePath The path of the file to ensure, as a string or URL.
 * @returns A void value that returns once the file exists.
 *
 * @example
 * ```ts
 * import { ensureFileSync } from "@std/fs/ensure-file";
 *
 * ensureFileSync("./folder/targetFile.dat");
 * ```
 */
export function ensureFileSync(filePath: string | URL): void {
  try {
    // if file exists
    const stat = Deno.lstatSync(filePath);
    if (!stat.isFile) {
      throw new Error(
        `Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`,
      );
    }
  } catch (err) {
    // if file not exists
    if (err instanceof Deno.errors.NotFound) {
      // ensure dir exists
      ensureDirSync(dirname(toPathString(filePath)));
      // create file
      Deno.writeFileSync(filePath, new Uint8Array());
      return;
    }
    throw err;
  }
}

// denoCacheMetadata={"headers":{"cf-cache-status":"HIT","age":"458713","cache-control":"public, max-age=31536000, immutable","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=qg277eZ7h7DdandgMyfdKXR9PAnCZKYg%2F07hS2VWyWQhGmXavhbdWYKujBwbY7UBf43kxVMxImbIs8N6aLm5Ck5I4XtFB1nbfLJqSotMPjQFk2opnpdYtcM%3D\"}]}","alt-svc":"h3=\":443\"; ma=86400","server":"cloudflare","x-content-type-options":"nosniff","cf-ray":"a223e656afd87db6-LAX","content-length":"2563","accept-ranges":"bytes","vary":"Origin","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","etag":"\"be41d968e7f2f3a24812ca8efac3c3b5\"","access-control-expose-headers":"*","date":"Tue, 28 Jul 2026 12:31:15 GMT","cross-origin-resource-policy":"cross-origin","content-security-policy":"default-src 'none'; script-src 'none'; style-src 'none'; img-src 'none'; font-src 'none'; connect-src 'none'; frame-src 'none'; object-src 'none'; frame-ancestors 'none'; sandbox; form-action 'none';","x-robots-tag":"noindex","x-jsr-backend":"modules","set-cookie":"__cf_bm=pLFKsVDW0qOOQ6Np89Cml.YpjhvHegFeJ.11h73j9OM-1785241874.9978242-1.0.1.1-fIdznfpAaCX01KD8O8DPCLOvA4luwyb8Hqwi4WZlsbFu0X4QnCOg.DAdkv8WLUxRBF91qa5Efffm6UAn6uKSW.Zh1sJpq6EqzovgsPRsyhsRXLLICN4PTpLooGEeE8ap; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","access-control-allow-origin":"*","content-type":"text/typescript"},"url":"https://jsr.io/@std/fs/0.224.0/ensure_file.ts","time":1785241875}