export interface RemoteCliOptions {
  host: string | null;
  user: string;
  port: number;
  projectRoot: string;
  identityFile: string | null;
  transport: "auto" | "frontend" | "ssh";
  args: string[];
}

const hostOptions = new Set(["--main-server-ip", "--main-server", "--server"]);
const userOptions = new Set(["--main-server-user", "--server-user"]);
const portOptions = new Set(["--main-server-port", "--server-port"]);
const rootOptions = new Set(["--main-server-root", "--server-root"]);
const keyOptions = new Set(["--main-server-key", "--server-key"]);
const transportOptions = new Set(["--main-server-transport", "--server-transport"]);

function positivePort(raw: string, option: string): number {
  const value = Number(raw);
  if (!Number.isInteger(value) || value <= 0 || value > 65535) throw new Error(`${option} must be a TCP port from 1 to 65535`);
  return value;
}

function requiredValue(argv: string[], index: number, option: string): string {
  const value = argv[index + 1];
  if (value === undefined || value.length === 0) throw new Error(`${option} requires a non-empty value`);
  return value;
}

function transportValue(raw: string, option: string): RemoteCliOptions["transport"] {
  if (raw === "auto" || raw === "frontend" || raw === "ssh") return raw;
  throw new Error(`${option} must be one of: auto, frontend, ssh`);
}

export function extractRemoteCliOptions(argv: string[]): RemoteCliOptions {
  const rest: string[] = [];
  const options: RemoteCliOptions = {
    host: null,
    user: "root",
    port: 22,
    projectRoot: "/root/unidesk",
    identityFile: null,
    transport: "auto",
    args: rest,
  };

  for (let index = 0; index < argv.length; index += 1) {
    const arg = argv[index] ?? "";
    if (arg === "--") {
      if (rest.length === 0) {
        rest.push(...argv.slice(index + 1));
        break;
      }
      rest.push(arg);
      continue;
    }
    if (hostOptions.has(arg)) {
      options.host = requiredValue(argv, index, arg);
      index += 1;
      continue;
    }
    if (userOptions.has(arg)) {
      options.user = requiredValue(argv, index, arg);
      index += 1;
      continue;
    }
    if (portOptions.has(arg)) {
      options.port = positivePort(requiredValue(argv, index, arg), arg);
      index += 1;
      continue;
    }
    if (rootOptions.has(arg)) {
      options.projectRoot = requiredValue(argv, index, arg);
      index += 1;
      continue;
    }
    if (keyOptions.has(arg)) {
      options.identityFile = requiredValue(argv, index, arg);
      index += 1;
      continue;
    }
    if (transportOptions.has(arg)) {
      options.transport = transportValue(requiredValue(argv, index, arg), arg);
      index += 1;
      continue;
    }
    rest.push(arg);
  }

  return options;
}
