// Agent-oriented structured reads: `outline` prints a versioned JSON
// document map built by the `docx2html/inspect` library package; see
// docs/agent-json-schemas.md for the normative payload spec.

///|
/// `docx outline ` — prints the `docx.outline/1` structure map.
async fn run_outline(matches : @argparse.Matches) -> Unit {
  let file = required_value(matches, "file")
  let data = @afs.read_file(file).binary()
  let annotated = @docx2html.read_docx_annotated(data)
  println(@inspect.annotated_outline(annotated, file~).stringify(indent=2))
}

///|
fn outline_command() -> @argparse.Command {
  Command("outline", about="Print a document structure map as JSON", positionals=[
    PositionArg(
      "file",
      about="Input .docx file.",
      num_args=ValueRange(lower=1, upper=1),
    ),
  ])
}

///|
/// `docx text ` — path-tagged plain text: one line per paragraph
/// (including table-cell paragraphs), prefixed with its `docx.element/1`
/// path so an agent can address what it reads.
async fn run_text(matches : @argparse.Matches) -> Unit {
  let file = required_value(matches, "file")
  let data = @afs.read_file(file).binary()
  let annotated = @docx2html.read_docx_annotated(data)
  for line in @inspect.annotated_text_lines(annotated) {
    println(line)
  }
}

///|
/// `docx get  ` — prints the element's raw text; with `--json`,
/// the full `docx.element/1` payload.
async fn run_get(matches : @argparse.Matches) -> Unit {
  let file = required_value(matches, "file")
  let path = required_value(matches, "path")
  let data = @afs.read_file(file).binary()
  let annotated = @docx2html.read_docx_annotated(data)
  // Path problems are usage errors, not document errors: agent-facing
  // messages already explain themselves, so give them the `error:` prefix.
  if matches.flags.get_or_default("json", false) {
    let payload = @inspect.annotated_element(annotated, file~, path~) catch {
      PathError(message) => raise @cli.CliError("error: " + message)
    }
    println(payload.stringify(indent=2))
  } else {
    let result = annotated.result()
    // Dispatch on the PARSED root (prefix sniffing would misroute
    // "/commentsX" — J2 review round 1).
    let parsed = @paths.parse_path(path) catch {
      PathError(message) => raise @cli.CliError("error: " + message)
    }
    let parsed_root_is_annotation = parsed.root
      is (Footnotes | Endnotes | Comments)
    let element = try {
      if parsed_root_is_annotation {
        @paths.resolve_annotation_path(
          path,
          footnotes=annotated.footnote_bodies(),
          endnotes=annotated.endnote_bodies(),
          comments=annotated.comment_bodies(),
        )
      } else {
        @inspect.resolve_path(
          result.document,
          path,
          headers=result.headers,
          footers=result.footers,
        )
      }
    } catch {
      PathError(message) => raise @cli.CliError("error: " + message)
    }
    println(element.to_raw_text().trim_end(chars="\n"))
  }
}

///|
fn required_value(
  matches : @argparse.Matches,
  name : String,
) -> String raise @cli.CliError {
  match first_value(matches, name) {
    Some(value) => value
    None =>
      raise CliError(
        "error: the following required argument was not provided: '\{name}'",
      )
  }
}

///|
fn text_command() -> @argparse.Command {
  Command(
    "text",
    about="Print path-tagged plain text, one paragraph per line",
    positionals=[
      PositionArg(
        "file",
        about="Input .docx file.",
        num_args=ValueRange(lower=1, upper=1),
      ),
    ],
  )
}

///|
fn get_command() -> @argparse.Command {
  Command(
    "get",
    about="Print one element by path (raw text, or JSON with --json)",
    flags=[
      FlagArg(
        "json",
        long="json",
        about="print the element as a structured JSON payload",
      ),
    ],
    positionals=[
      PositionArg(
        "file",
        about="Input .docx file.",
        num_args=ValueRange(lower=1, upper=1),
      ),
      PositionArg(
        "path",
        about="Element path, e.g. /body/p[3] (see 'docx text').",
        num_args=ValueRange(lower=1, upper=1),
      ),
    ],
  )
}