#!/usr/bin/python3
# debrequest --- generate Debian RFS/ITP requests

# Copyright (C) 2016 Dmitry Bogatov <KAction@gnu.org>

# Author: Dmitry Bogatov <kaction@gnu.org>

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Debrequest command line program collects machine-readable
information from files in debian/ directory of source
package and use is to generate RFS or ITP request.

Request formatted will be output on stdout and is well-formed
RFC822 message, suitable for piping to `/sbin/sendmail'.
"""

from debian.deb822 import Deb822
from debian.changelog import Changelog, get_maintainer
from glob import glob
from os.path import isfile, isdir
import argparse
import os.path
from jinja2 import Environment, PackageLoader, StrictUndefined


class attr_dict(dict):
    def __init__(self, *args, **kwargs):
        super(attr_dict, self).__init__(*args, **kwargs)
        self.__dict__ = self


def open_relative(path, root):
    return open(os.path.join(root, path))


def read_paragraphs(path, root):
    with open_relative(path, root) as f:
        return list(Deb822.iter_paragraphs(f))


def collect_information(root):
    info = attr_dict()
    (info.maintainer_name, info.maintainer_email) = get_maintainer()
    (source_p, *binary_ps) = read_paragraphs('debian/control', root)
    (upstream_p, *license_ps) = read_paragraphs('debian/copyright', root)
    changelog = Changelog(open_relative('debian/changelog', root))
    info.version = changelog.get_version()
    info.package_name = source_p['Source']
    info.upstream_name = upstream_p['Upstream-Name']
    info.binary_packages = [p['Package'] for p in binary_ps]
    info.section = source_p['Section']
    info.homepage = source_p['Homepage']
    info.upstream_author = upstream_p.get('Upstream-Contact',
                                          source_p['Maintainer'])
    try:
        info.short_description = source_p['X-Short-Desc']
        info.long_description = source_p['X-Long-Desc']
    except KeyError:
        (info.short_description, info.long_description) = binary_ps[0]['Description'].split('\n', 1)

    info.licenses = [par['License'].split('\n')[0].strip() for par in license_ps]
    info.licenses = list(set(info.licenses))
    info.changes = changelog._blocks[0]._changes
    info.upload_count = len(changelog._blocks)
    try:
        info.vcs_git = source_p['Vcs-Git']
    except KeyError as e:
        pass
    info.languages = []
    build_depends = [dep.strip().split()[0] for dep in source_p['Build-Depends'].split(",") if dep != '']
    if 'guile-2.0-dev' in build_depends:
        info.languages.append('GNU Guile')
    if 'dh-elpa' in build_depends:
        info.languages.append('Emacs Lisp')
    if isfile('configure.ac') or isfile('configure') or glob('*.c') != []:
        info.languages.append('C')
    if glob('*.cabal') != []:
        info.languages.append('Haskell')
    if glob('*.pm') != []:
        info.languages.append('Perl')
    if isfile('setup.py'):
        info.languages.append('Python')
    info.dgit = isdir(".git/refs/heads/dgit") or isdir('.git/dgit')
    return info

parser = argparse.ArgumentParser(description = __doc__)
parser.add_argument('--root', default = '.', help = 'root of source package')
parser.add_argument('mode', choices = ['RFS', 'ITP'], type = str.upper,
                    help = 'kind of request to generate')
args = parser.parse_args()
info = collect_information(args.root)

env = Environment(loader=PackageLoader('debrequest', 'templates'),
                  line_statement_prefix = '%% ',
                  trim_blocks = True,
                  lstrip_blocks = True,
                  undefined = StrictUndefined)
template = env.get_template(args.mode)
print(template.render(info))
