#!/usr/bin/python3

import os
import sys
import argparse
import itertools

from blends import Blend, aptcache, uddcache

default_release = "testing"

parser = argparse.ArgumentParser()

parser.add_argument("-d", "--dir", dest="dir", type=str,
                    default=".",
                    help="Base directory of the tasks source package"
                    + " (default: current directory)")

parser.add_argument("-r", "--release", dest="release", type=str,
                    default=default_release,
                    help="Target release, eg: stable, testing etc."
                    + " (default: {})".format(default_release))

parser.add_argument("-S", '--supress-empty', dest="suppressempty",
                    action="store_true", default=False,
                    help="suppress tasks without any recommended package")

parser.add_argument("-a", '--wanted', dest="wanted",
                    action="store_true", default=False,
                    help="print all wanted packages")

parser.add_argument("-m", '--missing', dest="missing",
                    action="store_true", default=False,
                    help="print missing packages")

parser.add_argument("-c", '--control', dest="gencontrol",
                    action="store_true", default=False,
                    help="Create new debian/control file.")

parser.add_argument("-t", '--taskdesc', dest="taskdesc",
                    action="store_true", default=False,
                    help="Generate task descriptions and package list for task")

parser.add_argument("-u", '--udebs', dest="udebs",
                    action="store_true", default=False,
                    help="Modify tasks desc file in case the blend uses udebs")

parser.add_argument("-F", '--upgrade-task-format', dest="upgrade_tasks",
                    action="store_true", default=False,
                    help="Upgrade tasks files to the latest format version")

parser.add_argument("-U", "--udd", dest="udd",
                    action="store_true", default=False,
                    help="Query UDD instead of apt (needs python3-psycopg2)")

parser.add_argument("--udd-host", dest="udd_host",
                    default="udd-mirror.debian.net",
                    help="UDD host name (default: udd-mirror.debian.net)")

parser.add_argument("--udd-user", dest="udd_user",
                    default="udd-mirror",
                    help="UDD user (default: udd-mirror)")

parser.add_argument("--udd-password", dest="udd_password",
                    default="udd-mirror",
                    help="UDD password (default: udd-mirror)")

parser.add_argument("--udd-database", dest="udd_database",
                    default="udd",
                    help="UDD database name (default: udd)")

if 'GENCONTROL_OPTS' in os.environ:
    opts = parser.parse_args(os.environ['GENCONTROL_OPTS'].split())
    parser.set_defaults(**opts.__dict__)

args = parser.parse_args()

if args.release == "current":
    args.release = None

blend = Blend(basedir=args.dir)

# For better performance, remove all tasks that will not create metapackages
for task in blend.tasks[:]:
    if not task.is_metapackage:
        blend.tasks.remove(task)

if args.udd:
    blend += uddcache(blend.all, args.release, host=args.udd_host,
                      user=args.udd_user, password=args.udd_password,
                      database=args.udd_database)
else:
    blend += aptcache(args.release, [args.dir, '/etc/blends'])

missing = sorted(set(d.name for d in blend.fix_dependencies()))
wanted = sorted(set(d.name for d in itertools.chain(*(
    itertools.chain(*(t.recommends + t.dependencies))
    for t in blend.tasks))))

if args.suppressempty:
    for task in blend.tasks[:]:
        if len(task.recommends) == 0 and len(task.dependencies) == 0:
            blend.tasks.remove(task)

if missing:
    if args.missing:
        print('Downgraded {} missing packages to Suggests:\n  '
              .format(len(missing))
              + '\n  '.join(missing))
    else:
        print('Downgraded {} missing packages to Suggests'
              .format(len(missing)))

if args.wanted:
    print("Total {} packages in Depends or Recommend:\n  "
          .format(len(wanted))
          + '\n  '.join(wanted))

if args.gencontrol:
    with open(os.path.join(args.dir, 'debian', 'control'), 'w') as fp:
        fp.write('# This file is autogenerated. Do not edit!\n')
        blend.gen_control().dump(fp, text_mode=True)
        print("Generated {} for {} with {} using {} Depends+Recommends"
              .format('debian/control',
                      args.release,
                      'udd' if args.udd else 'apt',
                      len(wanted)))

if args.taskdesc:
    with open(os.path.join(args.dir, '{}-tasks.desc'.format(blend.name)), 'w') as fp:
        blend.gen_task_desc(udeb=args.udebs).dump(fp, text_mode=True)
        print("Generated {} for {} with {} using {} Depends+Recommends"
              .format(blend.name + '-tasks.desc',
                      args.release,
                      'udd' if args.udd else 'apt',
                      len(wanted)))

upgraded_tasks = list(filter(lambda task: task.format_upgraded, blend.tasks))
if upgraded_tasks:
    if args.upgrade_tasks:
        print('Upgrading {} tasks from format version {}'
              .format(len(upgraded_tasks), upgraded_tasks[0].format_version))
        for task in upgraded_tasks:
            with open(os.path.join(args.dir, 'tasks', task.name), 'w') as fp:
                task.content.dump(fp, text_mode=True)
    else:
        print('Warning: {} tasks use the old format {}'
              .format(len(upgraded_tasks), upgraded_tasks[0].format_version))
        print('Please consider upgrading the task files with the `-F` flag.')
