"""
Main.
TODO list:
    main
        option to reset DB
    check/upgrade:
        remove plus suffixes in get_installed
    download:
        add option to keep existing files in wheelhouse
"""
__version__ = "1.1.2"
__dev_mode__ = False


import subprocess, argparse
try:
    from pip_dater.download import download
    from pip_dater.check import get_installed, check, check_outdated, probably_good_db
except:
    from download import download
    from check import get_installed, check, check_outdated, probably_good_db


def main(dev_stdout='', cmdline='', skip_download=False):
    parser = argparse.ArgumentParser(prog="pip-dater",
        description="A maintenance tool for the python packages.",
        formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("cmd", choices=["check", "upgrade", "download"],
                         help="check: perform integrity check on installed packages.\n"
                                "upgrade: upgrade the packages.\n"
                                "download: download the wheels for offline installation.")
    parser.add_argument("-v", "--version", action="version", version=__version__)
    parser.add_argument("-e", "--exclude", nargs="+", help="[upgrade] Exclude packages you don't want to upgrade")
    parser.add_argument("-y", "--yes", action="store_true", help="Automatically execute (no user prompt))")
    parser.add_argument("-n", "--no", action="store_true", help="Don't execute (no user prompt))")
    parser.add_argument("--archive", action="store_true", help="[download] Compress the wheelhouse")
    parser.add_argument("-i", "--include-dir", nargs=1, help="[download] Add all the files from the specified folder.")
    if cmdline:
        args = parser.parse_args(cmdline.split())
    else:
        args = parser.parse_args()

    # Common step: get installed packages/requirements
    req_installed = get_installed()
    print(f"Installed packages: {len(req_installed.splitlines())}")

    if args.cmd == 'check':
        print("Performing integrity test on installed packages")
        err, out = check(req_installed)
        if err:
            print('   Check failed! Log:\n', out)
        else:
            print('   Check passed.')
        return
    elif args.cmd == 'download':
        download(yes=args.yes, archive=args.archive, skip_download=skip_download,
                 include=args.include_dir[0] if args.include_dir else None)
        return
    elif args.cmd not in ('upgrade'):
        raise Exception('Unknown command!')


    ### CMD = UPGRADE (from here to end)
    print("Getting outdated packages")
    if dev_stdout:
        text = dev_stdout
    else:
        text = subprocess.run(['pip', 'list', '--outdated'],
                              capture_output=True, text=True).stdout
    outdated = [l.split()[:3] for l in text.splitlines()[2:]]  # skip header
    print(f"   Found {len(outdated)} outdated packages")
    print(f"   {[x[0] for x in outdated]}")
    excluded = args.exclude or []  # replace None
    print('Excluded from upgrade:', excluded)
    candidate = [x for x in outdated if x[0] not in excluded]
    print("Finding 'probably good' upgrades.")
    probably_good = probably_good_db(candidate, req_installed, verbose=True)
    print("Testing upgradable packages")
    good_candidate = check_outdated(req_installed, candidate, probably_good=probably_good)
    print(f"Upgradable packages: {len(good_candidate)}")
    if not good_candidate:
        print('Nothing to upgrade. DONE.')
        return

    print('To be upgraded:', good_candidate)
    if args.no:
        ans = 'n'
        print('   Upgrade skipped (--no flag in command line)')
    elif args.yes:
        ans = 'y'
        print('   Upgrade forced (--yes flag in command line)')
    else:
        ans = input('  Proceed with upgrade? (y/n) ')
    if ans.lower() in ('y', 'yes'):
        subprocess.run(['python', '-m', 'pip', 'install', '--upgrade'] + good_candidate)


############
if __name__ == "__main__":
    if not __dev_mode__:
        main()
    else:
        # DEVELOPMENT (remember to set __dev_mode__)
        # main(cmdline='-h')
        # main(cmdline='download -y --archive --include-dir test_include', skip_download=True)
        # main(cmdline='check')
        main(cmdline='upgrade -n -e pyinstaller selenium',
             dev_stdout="""Package     Version Latest Type
            ----------- ------- ------ -----
            autopep8    2.0.4   2.3.2  wheel
            debugpy     1.8.19  1.8.20 wheel
            flake8      7.1.2   7.3.0  wheel
            ipykernel   6.31.0  7.1.0  wheel
            jupyterlab  4.5.2   4.5.3  wheel
            nbconvert   7.16.6  7.17.0 wheel
            notebook    7.5.2   7.5.3  wheel
            psutil      7.2.1   7.2.2  wheel
            pycodestyle 2.12.1  2.14.0 wheel
            pycparser   2.23    3.0    wheel
            pyflakes    3.2.0   3.4.0  wheel
            pyinstaller 6.17.0  6.18.0 wheel
            pytokens    0.4.0   0.4.1  wheel
            QtAwesome   1.4.0   1.4.1  wheel
            scipy       1.16.3  1.17.0 wheel
            selenium    4.38.0  4.40.0 wheel
            tinycss2    1.4.0   1.5.1  wheel
            wcwidth     0.5.0   0.5.2  wheel""")
