// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { getFileInfoType } from "./_get_file_info_type.ts";

/**
 * Asynchronously ensures that the directory exists. If the directory structure
 * does not exist, it is created. Like `mkdir -p`.
 *
 * Requires the `--allow-read` and `--allow-write` flag.
 *
 * @param dir The path of the directory to ensure, as a string or URL.
 * @returns A promise that resolves once the directory exists.
 *
 * @example
 * ```ts
 * import { ensureDir } from "@std/fs/ensure-dir";
 *
 * await ensureDir("./bar");
 * ```
 */
export async function ensureDir(dir: string | URL) {
  try {
    const fileInfo = await Deno.stat(dir);
    if (!fileInfo.isDirectory) {
      throw new Error(
        `Ensure path exists, expected 'dir', got '${
          getFileInfoType(fileInfo)
        }'`,
      );
    }
    return;
  } catch (err) {
    if (!(err instanceof Deno.errors.NotFound)) {
      throw err;
    }
  }

  // The dir doesn't exist. Create it.
  // This can be racy. So we catch AlreadyExists and check stat again.
  try {
    await Deno.mkdir(dir, { recursive: true });
  } catch (err) {
    if (!(err instanceof Deno.errors.AlreadyExists)) {
      throw err;
    }

    const fileInfo = await Deno.stat(dir);
    if (!fileInfo.isDirectory) {
      throw new Error(
        `Ensure path exists, expected 'dir', got '${
          getFileInfoType(fileInfo)
        }'`,
      );
    }
  }
}

/**
 * Synchronously ensures that the directory exists. If the directory structure
 * does not exist, it is created. Like `mkdir -p`.
 *
 * Requires the `--allow-read` and `--allow-write` flag.
 *
 * @param dir The path of the directory to ensure, as a string or URL.
 * @returns A void value that returns once the directory exists.
 *
 * @example
 * ```ts
 * import { ensureDir } from "@std/fs/ensure-dir";
 *
 * await ensureDir("./bar");
 * ```
 */
export function ensureDirSync(dir: string | URL) {
  try {
    const fileInfo = Deno.statSync(dir);
    if (!fileInfo.isDirectory) {
      throw new Error(
        `Ensure path exists, expected 'dir', got '${
          getFileInfoType(fileInfo)
        }'`,
      );
    }
    return;
  } catch (err) {
    if (!(err instanceof Deno.errors.NotFound)) {
      throw err;
    }
  }

  // The dir doesn't exist. Create it.
  // This can be racy. So we catch AlreadyExists and check stat again.
  try {
    Deno.mkdirSync(dir, { recursive: true });
  } catch (err) {
    if (!(err instanceof Deno.errors.AlreadyExists)) {
      throw err;
    }

    const fileInfo = Deno.statSync(dir);
    if (!fileInfo.isDirectory) {
      throw new Error(
        `Ensure path exists, expected 'dir', got '${
          getFileInfoType(fileInfo)
        }'`,
      );
    }
  }
}

// denoCacheMetadata={"headers":{"content-length":"2770","access-control-expose-headers":"*","access-control-allow-origin":"*","cf-cache-status":"HIT","cf-ray":"a223e656afd77db6-LAX","server":"cloudflare","alt-svc":"h3=\":443\"; ma=86400","content-type":"text/typescript","vary":"Origin","x-robots-tag":"noindex","x-content-type-options":"nosniff","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=P74D62t%2Fw3qGDxQ4OewrY1cEAK8bZTNNITdo1aiuHNE%2BfwiIWnB%2Fcqv9EAbiAQFiAzy%2BSZmyYDnuGD1c%2Fgk%2BlPxn2FIoK%2BOfuZFoBMUAHc%2BjIQSOFuzVD9w%3D\"}]}","x-jsr-backend":"modules","cache-control":"public, max-age=31536000, immutable","etag":"\"371f8bc0db94850bd59e64a4a063bec3\"","cross-origin-resource-policy":"cross-origin","date":"Tue, 28 Jul 2026 12:31:15 GMT","accept-ranges":"bytes","age":"1014341","set-cookie":"__cf_bm=yAX_U0cc1wGZVTmGv.osc3sUqu1TfZuOOV1iFE88VVc-1785241874.9975262-1.0.1.1-YPS4TF5jX.CfdHNTyf2zN_Dn4ugkIAiKyBm.Nb9b9Tl7LSQgSxXZYOtEOmdmCw1SxAt6hA50yNmWw4UTuZ7ZXrLV9P24DFcJzS3hMXH0r3FCugDHcyyeiDmOjQGmWmhY; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","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';"},"url":"https://jsr.io/@std/fs/0.224.0/ensure_dir.ts","time":1785241875}