#include <tuple>

#include "argv.h"
#include "file.h"
#include "log.h"

using namespace std::string_literals;

fs::path construct_command_pathname(char* command)
{
    return fs::path(fs::current_path().string() + "/" + std::string(command));
}

void set_verbose_level(int argc, char* argv[])
{
    //command_name = absolute_pathname(argv[0]);
    command_name = std::string(argv[0]);
    command_pathname = construct_command_pathname(argv[0]);
    //std::cout << "set_verbose_level: " << command_pathname << "\n";

    Argv args {};
    args.opt("v", "'verbosity'", "level", "0", "'verbosity'");
    args.parse(argc, argv, false);
    verbose_level = args.as_verbosity("v");
}

bool show_usage(int argc, char* argv[])
{
    return argc == 1 || (argc == 3 && std::string(argv[1]) == "-v"s);
}

std::string construct_output_filename(
    const std::string& output_dir, const std::string& output_basename, const std::string& target)
{
    std::string result {};
    if (target == "html") {
        result = output_dir + "/" + output_basename + "/index.html";
    } else {
        result = output_dir + "/" + output_basename + "." + target;
    }
    return result;
}

bool only_definitions(std::vector<std::string> filenames)
{
    if (filenames.empty()) return false;
    bool result = true;
    for (auto f : filenames) {
        if (fs::path(f).extension() != ".k") {
            result = false;
            break;
        }
    }
    return result;
}

std::tuple<std::string, std::string, std::string, std::string, bool, bool>
parse_args(
    const std::vector<std::string>& input_filenames, std::string target, std::string output_basename, bool display_only)
{
    // output_dir
    std::string output_target = target;
    std::string output_dir = "";
    std::string ext = extension(output_basename);
    // std::string output_filename = "";
    bool write_files = true;
    if (target.empty() && output_basename.empty()) {
        output_target = "any";
    }
    if (output_basename == "-") {
        write_files = false;
    } else if (!output_basename.empty()) {
        output_dir = file_directory(output_basename);
        output_basename = file_basename(output_basename);
    } else if (!input_filenames.empty()) {
        output_dir = "";  // defaults to cwd via absolute_pathname below
        output_basename = file_basename(input_filenames[0]);
    }
    output_dir = absolute_pathname(output_dir);
        
    if (output_target.empty()) {
        target = ext;
    }

    std::string output_filename =
        construct_output_filename(output_dir, output_basename, target);

    if (output_basename.empty() && input_filenames.empty()) {
        display_only = true;
    } else if (only_definitions(input_filenames)) {
        display_only = true;
    }

    std::vector<std::pair<std::string,std::string>> vars = {
        {"Output target", output_target},
        {"Output directory", output_dir},
        {"Output basename", output_basename},
        {"Output filename", output_filename},
        {"Write file", write_files ? "true" : "false"}};

    int verbose = 1;
    for (auto [label, value] : vars) {
        if (label == "Output filename") {
            //verbose = 2;
        }
        (void)K::log(int(verbose), label + ":", value);
    }
    return {output_target, output_dir, output_basename, output_filename, write_files, display_only};
}
