#include "argv.h"
#include "command.h"
#include "error.h"
#include "file.h"
#include "ktype.h"
#include "log.h"
#include "argtype_set.h"
#include "character.h"
#include "show.h"
#include "util.h"

int main(int argc, char* argv[])
{
    try {
        set_verbose_level(argc, argv);

        Argv args {};
        args.flag("c", "Special characters");
        args.flag("a", "Argument types");
        args.flag("k", "Katom types");
        args.flag("r", "Katom rewrite patterns");
        args.opt("input", "Input filename", "filename", "", "'text'");
        args.flag("targets", "Show targets defined by the input file");
        args.flag("klammers", "Show klammers defined by the input file");
        args.opt("v",  "'verbosity'", "n", "0", "'verbosity'");

        if (show_usage(argc, argv)) {
            args.usage(file_basename(argv[0]));
            exit(1);
        }
        auto p = [&](std::string name) { return args.get(name) == "true"; };

        args.parse(argc, argv);
        verbose_level = stoi(args.get("v"));
        if (verbose_level > 0) {
            args.describe();
        }

        if (p("c")) {
            show_special_characters();
            std::cout << "\n";
        }

        if (p("a")) {
            Argtype_set argtypes;
            std::cout << boldblack << "\nStandard klammer argument types\n" << black;
            std::cout << argtypes.describe() << "\n";
        }

        if (p("k")) {
            describe_katoms(verbose_level > 2);
        }

        if (p("r")) {
            describe_rewrite_patterns();
        }

        Machine M;

        strings_t input_filenames = args.as_vector("input");
        std::cout << "input_filenames: " << input_filenames << "\n";
        if (input_filenames.empty()) {
            M.read(fs::path(M.m_state.value("KLAMMERTEXT_HOME") + "/sks/sks.k"));
        } else {
            for (auto fname : input_filenames) {
                std::cout << "Read " << fname << "\n";
                M.read(fs::path(absolute_pathname(fname)));
            }
        }

        if (p("targets")) {
            std::cout << boldblack << "Targets\n" << black << M.m_targets.describe(2, true);
        }

        if (p("klammers")) {
            std::cout << boldblack << "Klammers\n" << black << M.m_klammers.describe(2);
        }

    }
    catch (Error& e) {
        e.print_message();
    }
}
