{ format.a68 - godcc format sub-command.

  Copyright (C) 2026 Jose E. Marchesi

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see
  <https://www.gnu.org/licenses/>. }

module Format =
    access Utils, Argp, JSON, CE, Globals
def
    pub proc godcc_format = (int pos) void:
    begin
          string style, src_file, out_file;

          { Some defaults. }
          int tab_width := 4;
          bool use_spaces := false;
          string formatter := "clangformat";
          src_file := out_file := "-";

          { Parse command-line options for the sub-command. }
          argp(pos, []ArgOpt (("o", "", true,
                               (string arg) bool: (out_file := arg; true)),
                              ("f", "formatter", true,
                               (string arg) bool: (formatter := arg; true)),
                              ("s", "style", true,
                               (string arg) bool: (style := arg; true)),
                              ("t", "tab-width", true,
                               (string arg) bool: (tab_width := atoi (arg, 10); true)),
                              ("s", "use-spaces", false,
                               (string arg) bool: (use_spaces := true))),
               (int pos, string no_opt_arg) bool:
                  (if src_file /= "-"
                   then error("please specify exacly one source file to format")
                   fi;
                   src_file := no_opt_arg;
                   true),
               error);

          { Determine the formatting style to use. }
          style := (style = ""
                    | (formatter = "clangformat" | "GNU")
                    | style);

          { Open the input file and read its contents. }
          ref string src = read_from_file(src_file);

          { Prepare the JSON query. }
          JSON_Val cmd := json_new_obj;
          cmd->"source" := json_escape_string(src);
          cmd->"base" := style;
          cmd->"useSpaces" := use_spaces;
          cmd->"tabWidth" := tab_width;

          { Query the server. }
          ce_connect;
          JSON_Val res := ce_post_json("format/" + formatter, cmd);
          ce_disconnect;

          { Process the response. }
          string answer = json_str(res->"answer");
          int exit_status = json_int(res->"exit");
          (exit_status /= 0 | error(answer));

          { Write the formatted code to the output file. }
          write_to_file(out_file, answer)
    end;

    skip
fed
