// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

/**
 * Unified install-ref dispatcher.
 *
 * Replaces the historical `installRegistryRef()` entry point. Given an
 * unparsed install ref, this resolves the right syncable provider and
 * invokes its `sync()` method.
 */

import type { SourceSpec } from "../../core/config/config";
import { UsageError } from "../../core/errors";
import { parseRegistryRef } from "../../registry/resolve";
import type { ParsedLocalRef } from "../../registry/types";
import type { SourceLockData, SyncOptions } from "./install-types";
import { detectStashRoot } from "./provider-utils";

export async function syncFromRef(ref: string, options?: SyncOptions): Promise<SourceLockData> {
  const parsed = parseRegistryRef(ref);
  if (parsed.source === "local") {
    return syncLocalRef(parsed, options);
  }
  if (parsed.source === "npm") {
    const { syncNpmRef } = await import("./npm");
    return syncNpmRef(ref, options);
  }
  if (parsed.source === "git" || parsed.source === "github") {
    const { syncRegistryGitRef } = await import("./git");
    return syncRegistryGitRef(ref, options);
  }
  // Exhaustiveness — `parseRegistryRef` only emits the four sources above.
  throw new UsageError(
    `No syncable provider for ref: ${ref} (source=${(parsed as { source: SourceSpec["type"] }).source})`,
  );
}

function syncLocalRef(parsed: ParsedLocalRef, options?: SyncOptions): SourceLockData {
  const stashRoot = detectStashRoot(parsed.sourcePath);
  const syncedAt = (options?.now ?? new Date()).toISOString();
  return {
    id: parsed.id,
    source: "local",
    ref: parsed.ref,
    artifactUrl: parsed.sourcePath,
    contentDir: stashRoot,
    cacheDir: parsed.sourcePath,
    extractedDir: parsed.sourcePath,
    writable: options?.writable,
    syncedAt,
  };
}
