# Bracket command interpreter

# Copyright (c) 2020-2023 Andreas Gustafsson.  All rights reserved.
# Please refer to the file COPYRIGHT for detailed copyright information.

import argparse
import optparse
import sys

from bracket import *

from __main__ import docdir

def usage():
    print('''usage: bracket <command> [arguments]
For more information, see %s.''' % os.path.join(docdir, 'README'),
          file = sys.stderr)
    sys.exit(1)

def bracket_command(argv):
    if len(argv) < 1:
        usage()

    cmd = argv[0]
    args = argv[1:]

    def ts_from_arg(source_date = None):
        if source_date is None:
            source_date = args[0]
        return sourcedate2ts(source_date)

    if cmd == 'build':
        test(build_op, ts_from_arg())
        # update_reports() was called in do_build()
    elif cmd == 'install':
        test(install_op, ts_from_arg())
        update_reports()
    elif cmd == 'test':
        test(test_op, ts_from_arg())
        update_reports(args)
    elif cmd == 'interact':
        force(install_op, ts_from_arg())
        # None means do not redirect stdout and stderr
        anita_run_2(ts_from_arg(), 'interact', None, args[1:])
    elif cmd == 'notify':
        from notify import notify_main
        notify_main(args)
    elif cmd == 'refine':
        from refine import refine_main
        refine_main(args)
    elif cmd == 'schedule':
        from schedule import schedule_main
        schedule_main(args)
    elif cmd == 'update-reports':
        update_reports(args)
    elif cmd == 'publish-reports':
        publish_reports()
    elif cmd == 'update-repository':
        update_repository()
    elif cmd == 'update-resource-reports':
        from timeplot import timeplot_main
        timeplot_main(args)
    elif cmd == 'print-rcsdate':
        # Need to make sure stdout is free from debug output
        saved_stdout = sys.stdout
        sys.stdout = open("/dev/null", "w")
        rcsdate = ts2rcs(ts_from_arg())
        sys.stdout = saved_stdout
        print(rcsdate)
    elif cmd == 'update-repository':
        use_repository_for(ts_from_arg())
    elif cmd == 'test-patch-server':
        from test_patch_server import test_patch_server_main
        test_patch_server_main(args)
    elif cmd == 'run-external-test':
        r = run_external_test(args[0], args[1:])
        if not r:
            sys.exit(1)
    elif cmd == 'run-external-tests':
        r = run_external_tests(args[0], args[1:])
        if not r:
            sys.exit(1)
    elif cmd == 'bisect':
        parser = argparse.ArgumentParser()
        parser.add_argument('--auto', action='store_true')
        parser.add_argument('--no-confirm', action='store_false', dest='confirm')
        parser.add_argument('--fix', action='store_true', dest='sense')
        parser.add_argument('args', nargs=argparse.REMAINDER)
        opts = parser.parse_args(args)
        args = opts.args
        if not opts.auto:
            ts0 = ts_from_arg(args.pop(0))
            ts1 = ts_from_arg(args.pop(0))
            sense = opts.sense
        op = test_args2op(args)
        if opts.auto:
            if opts.sense:
                raise RuntimeError("can't use --fix with --auto")
            sense, ts0, ts1 = find_last_change_fast(op)
        find_change(ts0, ts1, op,
            sense = sense, confirm = opts.confirm)
    elif cmd == 'print-atf-summary':
        parser = optparse.OptionParser()
        parser.add_option("--mail", action="store_true")
        options, args = parser.parse_args(args)
        if options.mail:
            do_mail = True
            do_print = False
        else:
            do_mail = False
            do_print = True
        n_runs = 40
        if len(args) > 0:
            n_runs = int(args[0])
        summarize_atf_changes(None, n_runs, do_mail, do_print)
    elif cmd == 'run':
        sys.argv = args
        exec(open(args[0]).read(), globals(), globals())
    elif cmd == 'setup':
        setup()
    elif cmd == 'upgrade':
        run(os.path.join(libdir, 'upgrade.sh'), verbose = False)
    elif cmd == 'build-all':
        build_all()
    elif cmd == 'renotify':
        maybe_report_status_change(rcs2ts(args[0]), args[1])
    elif cmd == 'print-test-dir':
        print(test_dir(rcs2ts(args[0])))
    elif cmd == 'print-lock-state':
        for fn in args:
            lock = trylock(fn)
            # If we could lock it, it is not locked by anyone else
            print(fn, "is not" if lock else "is", "locked")
            del lock
    elif cmd == 'each':
        ts0 = ts_from_arg(args.pop(0))
        ts1 = ts_from_arg(args.pop(0))
        cno = ts2cno(ts0)
        while True:
            ts = cno2ts(cno)
            def subst_t(s):
                if s == 't':
                    return ts2rcs(ts)
                else:
                    return s
            print("next commit is", ts2rcs(ts))
            try:
                bracket_command([subst_t(s) for s in args])
            except Exception as e:
                # Perhaps in progress
                print(e)
                print("failed, trying the next commit")
            cno += 1
            if ts == ts1:
                break
    elif cmd == 'print-timestamp':
        print(ts2rcs(ts_from_arg()))
    else:
        print("unknown command", cmd)
        usage()
