from __future__ import print_function

import argparse
import os
import sys


def project_dir(fname=os.curdir):
    return os.path.join(os.path.dirname(os.path.abspath(__file__)), fname)


def read_file(fname):
    if isinstance(fname, basestring):
        with open(fname) as fd:
            return fd.read()
    if isinstance(fname, file):
        return fname.read()


class Arg(object):
    class Delegate(object):
        def __init__(self, f, p):
            self.p = p
            self.f = f

        def __call__(self, *args, **kwargs):
            return self.f(*args, **kwargs)

    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("--help", action="help")
    subparsers = parser.add_subparsers(metavar="ACTION")

    def __init__(self, *args, **kwargs):
        self.args, self.kwargs = args, kwargs

    def __call__(self, f):
        if isinstance(f, self.Delegate):
            f.p.add_argument(*self.args, **self.kwargs)
            return f
        else:
            p = self.subparsers.add_parser(f.__name__, help=f.__doc__, add_help=False)
            p.add_argument("--help", action="help")
            p.set_defaults(_target_function=f)
            if self.args or self.kwargs:
                p.add_argument(*self.args, **self.kwargs)
            return self.Delegate(f, p)

    @classmethod
    def run(cls):
        p = cls.parser.parse_args()
        # noinspection PyProtectedMember
        p._target_function(**{k: v for k, v in vars(p).items() if not k.startswith("_")})

    if len(sys.argv) < 2:
        print("Usage: {} ()")
