# MIT License

# Copyright (c) 2025 Ashlin Iser, Karlsruhe Institute of Technology (KIT)

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

import argparse
import os
import re


def get_gbd_argparser():
    parser = argparse.ArgumentParser(description="GBD Benchmark Database")
    parser.add_argument("-d", "--db", type=gbd_db_type, default=os.environ.get("GBD_DB"), help="Specify database to work with")
    parser.add_argument("-v", "--verbose", action="store_true", help="Print additional (or diagnostic) information to stderr")
    return parser


def add_query_and_hashes_arguments(parser: argparse.ArgumentParser):
    parser.add_argument("query", help="GBD Query", nargs="?")
    parser.add_argument(
        "--hashes", help="Explicitly select instances: Hashes can be passed as arguments to this option, but also via <stdin>.", nargs="*", default=[]
    )


def add_resource_limits_arguments(parser: argparse.ArgumentParser):
    parser.add_argument("-j", "--jobs", default=1, type=int, help="Set number of parallel jobs")
    parser.add_argument(
        "-t",
        "--tlim",
        default=5000,
        type=int,
        help="Time limit (sec) per instance for 'init' sub-commands (also used for score calculation in 'eval' and 'plot')",
    )
    parser.add_argument("-m", "--mlim", default=2000, type=int, help="Memory limit (MB) per instance for 'init' sub-commands")
    parser.add_argument("-f", "--flim", default=1000, type=int, help="File size limit (MB) per instance for 'init' sub-commands which create files")


### Argument Types for Input Sanitation in ArgParse Library
def directory_type(path):
    if not os.path.isdir(path):
        raise argparse.ArgumentTypeError("{0} is not a directory".format(path))
    if os.access(path, os.R_OK):
        return os.path.abspath(path)
    else:
        raise argparse.ArgumentTypeError("{0} is not readable".format(path))


def file_type(path):
    if not os.path.isfile(path):
        raise argparse.ArgumentTypeError("{0} is not a regular file".format(path))
    if os.access(path, os.R_OK):
        return os.path.abspath(path)
    else:
        raise argparse.ArgumentTypeError("{0} is not readable".format(path))


def column_type(s):
    pat = re.compile(r"^[a-zA-Z][a-zA-Z0-9_]*$")
    if not pat.match(s):
        raise argparse.ArgumentTypeError('Column "{0}" does not match regular expression {1}'.format(s, pat.pattern))
    return s


def key_value_type(s):
    tup = s.split("=", 1)
    if len(tup) != 2:
        raise argparse.ArgumentTypeError("key-value type: {0} must be separated by exactly one = ".format(s))
    return (column_type(tup[0]), tup[1])


def gbd_db_type(dbstr):
    if not dbstr:
        default = os.environ.get("GBD_DB")
        if not default:
            raise argparse.ArgumentTypeError("Datasources Missing: Set GBD_DB environment variable (Find databases here: https://benchmark-database.de)")
        return default  # .split(':')
    return dbstr
