#!/usr/bin/sh
#
# Copyright (c) 2010-2012 Red Hat, Inc.
#
# 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 2 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/.


# Check the correct Python executable to run this file.
# Python3 will be preferred.
""":"

cmd=$(python-check.sh)

exec -- $cmd $0 "$@";

":"""
from __future__ import print_function

"""
Tool to generate a specfile, based on a list of testinfo.desc filenames
"""

import sys
import re
import os
import codecs

import rhts.testinfo

# Ordinarily we would want to respect the locale encoding and all that jazz,
# when we write unicode to stdout. But this script is specifically designed for
# piping stdout to a file to produce the .spec, which is always UTF-8 encoded.
# So let's just hack it:
# sys.stdout = codecs.getwriter('utf8')(sys.stdout)

def get_tarball_name(name, version, release):
    return "%s-%s-%s.tar.gz"%(name, version, release)

def generate_specfile(testinfos, name, version, release, strictRequires, strictABI, provides, url):
    """Given a list of Testinfo instances, print a specfile suitable for building a package of the test"""
    assert len(testinfos)>0

    if len(testinfos)==1:
        testinfo = testinfos[0]

    if len(testinfos)>1:
        print("Summary:        Collection of automated tests")
    else:
        print('Summary:        RHTS test "%s"'%testinfo.test_name)
        
    print("Name:           %s"%name)
    print("Version:        %s"%version)
    print("Release:        %s"%release)
    print("Group:          System Environment/Base")
    print("URL:            %s" % url)
    if len(testinfos)>1:
        print("License:        various")
    else:
        print("License:        %s"%testinfo.license)
        
    print("Buildroot:      %{_tmppath}/%{name}-%{version}-root")
    if not strictABI:
        print("BuildArch: noarch")
    print("")
    print("# Tests need the testing env package to be runnable:")
    print("Requires: rhts-test-env")
    print("")
    extra_provides = provides
    for test in testinfos:
        print("# Provides/Requires for test '%s'"%test.test_name)
        print("Provides: test(%s) = %s-%s" % (test.test_name, version, release))
        for provides in test.provides + extra_provides:
            # RPM Dependency tokens must begin with alpha-numeric, '_' or '/':
            if re.match('^[A-Za-z0-9_/].*$', provides):
                print("Provides: %s = %s-%s" % (provides, version, release))
            else:
                print("# testinfo requirement not usable in specfile: Provides: %s" % provides)
        for requires in test.rhtsrequires:
            # RPM Dependency tokens must begin with alpha-numeric, '_' or '/':
            if re.match('^[A-Za-z0-9_/].*$', requires):
                print("Requires: %s"%requires)
            else:
                print("# testinfo requirement not usable in specfile: Requires: %s"%requires)
        for requires in test.requires:
            # RPM Dependency tokens must begin with alpha-numeric, '_' or '/':
            if strictRequires:
                if re.match('^[A-Za-z0-9_/].*$', requires):
                    print("Requires: %s"%requires)
                else:
                    print("# testinfo requirement not usable in specfile: Requires: %s"%requires)
            else:
                print("# requirement generation disabled; not adding Requires: %s"%requires)
        for runfor in test.runfor:
            print("Provides: test-of(%s)-%s = %s-%s" % (runfor, test.test_name, version, release))
            print("# from RunFor: %s"%runfor)
            # so that you can "yum install test-of(somepackage)\*" and it will pull
            # in all tests
        print("")
    if not strictABI:
        print("AutoReqProv: no:")
    print("")
    print("Source0:	%s"%get_tarball_name(name, version, release))
    print("")
    print("%define _source_filedigest_algorithm 0")
    print("%define _binary_filedigest_algorithm 0")
    print("%define _source_payload       w9.gzdio")
    print("%define _binary_payload       w9.gzdio")
    print("%define __debug_install_post %{nil}  ")
    print("%define __spec_install_post %{__debug_install_post}  /usr/lib/rpm/brp-compress || :")
    print("")
    print("%description")
    if len(testinfos)>1:
        print("This package contains automated tests")
    else:
        print(testinfo.test_description)
    print("")
    print("%prep")
    print("")
    print("%setup -q -c ")
    print("")
    print("%build")
    print('[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;')
    print("mkdir -p %{buildroot}/mnt/tests")
    if strictABI:
        print("make DEST=$RPM_BUILD_ROOT build")
    print("")
    print("")
    print("%install")
    print("mkdir -p %{buildroot}/mnt/tests")
    print("")
    print("make DEST=$RPM_BUILD_ROOT install")
    if strictABI:
        print("make DEST=$RPM_BUILD_ROOT install-built-files")
    print("")
    print("chmod -R a-s  %{buildroot}")
    print("")
    print("%clean")
    print('[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;')
    print("")
    print("")
    print("%files")
    print("%defattr(-,root,root,0755)")
    print("/mnt/tests")
    print("")
    print("%changelog")
    if len(testinfos)>1:
        author = testinfos[0].owner # arbitrarily pick owner of first test
    else:
        author = testinfo.owner
    print("* Fri May 26 2006	%s - %s-%s"%(author, version, release))
    print("- Autogenerated specfile")
    print("")

def test():
    ti = rhts.testinfo.parse_string("""\
    # Test comment
    Owner:        Jane Doe <jdoe@redhat.com>
    Name:         /examples/coreutils/example-simple-test
    Path:         /mnt/tests/examples/coreutils/example-simple-test
    Description:  This test ensures that md5sums are generated and validated correctly
    TestTime:     1m
    TestVersion:  1.0
    License:      GPLv2+
    RunFor:       coreutils
    Requires:     coreutils python
    """)


    package = "foo"
    name = "rhts-%s-tests"%package
    version = "1.0"
    release = 64
    url = 'git://test'
    generate_specfile([ti], name, version, release, url=url)

def parse_file(filename):
    p = rhts.testinfo.StderrParser(filename)
    p.parse(codecs.open(filename, 'rb', 'utf8').readlines())
    if p.numErrors>0:
        sys.exit(1)
    return p.info

from optparse import OptionParser
optparser = OptionParser(description="Generate an Job for the Red Hat Test System")

if __name__=='__main__':
    parser = OptionParser(usage = "usage: %prog [options] name version release")
    # We might not want to automatically add Requires: for RPMs based on
    # the Requires: in testinfo.desc files - see documentation of testinfo.desc files
    # An implementation is currently allowed to silently ignore ignore
    # unsolvable dependencies (to deal with a package changing names between distro releases etc)
    parser.add_option('', "--strict-requires", dest="strictRequires", action='store_true', default=False,
                      help="add Requires to RPM metadata based on entries in testinfo.desc files")
    parser.add_option('', "--strict-abi", dest="strictABI", action='store_true', default=False,
                      help="generate a specfile in which compilation is done during the package build, rather than at test time")
    parser.add_option('', "--provides", dest='provides', action='append',
        help="Additional provides to pass to spec file")
    parser.add_option('--url', help='URL for the task', default='NO_URL_SPECIFIED')
    (options, args) = parser.parse_args()
    #print options
    #print args
    if len(args) != 3:
        parser.error("incorrect number of arguments")
    (name, version, release) = args
    testinfoFiles = []
    for filename in sys.stdin.readlines():
        filename = filename.strip()
        testinfoFiles.append(parse_file(filename))
    #print testinfoFiles
    if len(testinfoFiles)==0:
        print("No testinfo.desc filenames on stdin")
        sys.exit (1)
    generate_specfile(testinfoFiles, name, version, release,
        strictRequires=options.strictRequires, strictABI=options.strictABI,
        provides=options.provides, url=options.url)
