#!/usr/bin/env bash
set -euo pipefail

node - "$@" <<'NODE'
const args = process.argv.slice(2);
let vault = "";
let file = "";
let line = "";
let column = "";
let obsidianUrl = "";
let host = "https://links.xfiner.com/";

function usage() {
  console.error("Usage:");
  console.error("  build_obsid_link.sh --vault <vault> --file <file-path> [--line <line>] [--column <column>] [--host https://links.xfiner.com/]");
  console.error("  build_obsid_link.sh --obsidian-url <obsidian://open|open-line?...> [--host https://links.xfiner.com/]");
}

for (let i = 0; i < args.length; i += 1) {
  const arg = args[i];
  if (arg === "--vault") {
    vault = args[i + 1] || "";
    i += 1;
  } else if (arg === "--file") {
    file = args[i + 1] || "";
    i += 1;
  } else if (arg === "--line") {
    line = args[i + 1] || "";
    i += 1;
  } else if (arg === "--column") {
    column = args[i + 1] || "";
    i += 1;
  } else if (arg === "--obsidian-url") {
    obsidianUrl = args[i + 1] || "";
    i += 1;
  } else if (arg === "--host") {
    host = args[i + 1] || host;
    i += 1;
  } else if (arg === "-h" || arg === "--help") {
    usage();
    process.exit(0);
  } else {
    console.error("Unknown argument: " + arg);
    usage();
    process.exit(1);
  }
}

if (obsidianUrl) {
  let parsed;
  try {
    parsed = new URL(obsidianUrl);
  } catch {
    console.error("Error: invalid --obsidian-url value");
    process.exit(1);
  }

  if (parsed.protocol !== "obsidian:" || !["open", "open-line"].includes(parsed.hostname)) {
    console.error("Error: --obsidian-url must start with obsidian://open or obsidian://open-line");
    process.exit(1);
  }

  vault = parsed.searchParams.get("vault") || vault;
  file = parsed.searchParams.get("file") || file;
  line = parsed.searchParams.get("line") || line;
  column = parsed.searchParams.get("column") || column;
}

if (!vault || !file) {
  console.error("Error: both vault and file are required.");
  usage();
  process.exit(1);
}

if (!host.endsWith("/")) {
  host += "/";
}

function isPositiveInteger(value) {
  const number = Number(value);
  return /^d+$/.test(value) && Number.isSafeInteger(number) && number > 0;
}

if (line && !isPositiveInteger(line)) {
  console.error("Error: --line must be a positive integer.");
  process.exit(1);
}

if (column && (!line || !isPositiveInteger(column))) {
  console.error("Error: --column requires a positive --line and must be a positive integer.");
  process.exit(1);
}

const normalizedFile = file.replace(/\\/g, "/");
let output =
  host +
  "?vault=" + encodeURIComponent(vault) +
  "&file=" + encodeURIComponent(normalizedFile);

if (line) {
  output += "&line=" + encodeURIComponent(line);
}

if (column) {
  output += "&column=" + encodeURIComponent(column);
}

console.log(output);
NODE
