#!/usr/bin/python -tt
# vim: ai ts=4 sts=4 et sw=4

#    Copyright (c) 2009 Intel Corporation
#
#    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; version 2 of the License
#
#    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, write to the Free Software Foundation, Inc., 59
#    Temple Place - Suite 330, Boston, MA 02111-1307, USA.

from __future__ import with_statement

import os,sys
import optparse
import glob

from spectacle import specify
from spectacle import logger

MF_TEMPLATE = """PKG_NAME := %s
SPECFILE = $(addsuffix .spec, $(PKG_NAME))
YAMLFILE = $(addsuffix .yaml, $(PKG_NAME))


include /usr/share/packaging-tools/Makefile.common
"""

def new_yaml(fpath):
    from spectacle import dumper
    if not fpath.endswith('.yaml'):
        fpath += '.yaml'

    autokeys = list(specify.MAND_KEYS) + ['Sources', 'Requires', 'PkgBR', 'PkgConfigBR']
    items = []
    for key in autokeys:
        if key in specify.STR_KEYS:
            items.append((key, '^^^'))
        elif key in specify.LIST_KEYS:
            items.append((key, ['^^^']))

    dumper = dumper.SpectacleDumper(format='yaml', opath = fpath)
    dumper.dump(items)
    # append comments
    with open(fpath, 'a') as f:
        f.write("""# Please replace all "^^^" with valid values, or remove the unused keys.
# And cleanup these comments lines for the best.
""")
    logger.info('New spectacle yaml file created: %s' % fpath)
    if logger.ask('Continue to edit the new file?'):
        if 'EDITOR' in os.environ:
            editor = sys.environ['EDITOR']
        else:
            editor = 'vi'
        os.system('%s %s' % (editor, fpath))

def new_subpkg(fpath, sub):
    def _has_subs(path):
        import re
        with open(path) as f:
            lines = f.read()
        if re.search('^SubPackages:', lines, re.M):
            return True
        else:
            return False

    if _has_subs(fpath):
        str_sub = '\n'
    else:
        str_sub = '\nSubPackages:\n'
    str_sub +="""    - Name:  %s
      Summary: ^^^
      Group: ^^^
# Please replace all "^^^" with valid values, and cleanup this comment line.
""" % sub

    with open(fpath, 'a') as f:
        f.write(str_sub)

def parse_options(args):
    import spectacle.__version__

    usage = "Usage: %prog [options] [yaml-path]"
    parser = optparse.OptionParser(usage, version=spectacle.__version__.VERSION)

    parser.add_option("-o", "--output", type="string",
                      dest="outfile_path", default=None,
                      help="Path of output spec file")
    parser.add_option("-s", "--skip-scm", action="store_true",
                      dest="skip_scm", default=False,
                      help="Skip to check upstream SCM when specified in YAML")
    parser.add_option("-N", "--not-download", action="store_true",
                      dest="not_download", default=False,
                      help="Do not try to download newer source files")
    parser.add_option("-n", "--non-interactive", action="store_true",
                      dest="noninteractive", default=False,
                      help="Non interactive running, to use default answers")
    parser.add_option("", "--new", type="string",
                      dest="newyaml", default=None,
                      help="Create a new yaml from template")
    parser.add_option("", "--newsub", type="string",
                      dest="newsub", default=None,
                      help="Append a new sub-package to current yaml")

    return parser.parse_args()

if __name__ == '__main__':
    """ Main Function """

    (options, args) = parse_options(sys.argv[1:])

    if options.noninteractive:
        logger.set_mode(False)

    if options.newyaml:
        if glob.glob('*.yaml'):
            if not logger.ask('Yaml file found in current dir, continue to create a new one?', False):
                sys.exit(0)

        elif glob.glob('*.spec'):
            if not logger.ask('Spec file found in current dir, maybe you need spec2spectacle to convert it, continue?', False):
                sys.exit(0)

        new_yaml(options.newyaml)
        sys.exit(0)

    if not args:
        # no YAML-path specified, search in CWD
        yamlls = glob.glob('*.yaml')
        if not yamlls:
            logger.error('Cannot find valid spectacle file(*.yaml) in current directory, please specify one.')
        elif len(yamlls) > 1:
            logger.error('Find multiple spectacle files(*.yaml) in current directory, please specify one.')

        yaml_fpath = yamlls[0]
    else:
        yaml_fpath = args[0]

    # check if the input file exists
    if not os.path.isfile(yaml_fpath):
        # input file does not exist
        logger.error("%s: File does not exist" % yaml_fpath)

    if options.newsub:
        new_subpkg(yaml_fpath, options.newsub)
        logger.info('Yaml file: %s has been appended with new subpkg: %s' % (yaml_fpath, options.newsub))
        sys.exit(0)

    if options.outfile_path:
        if os.path.sep in options.outfile_path:
            out_fpath = os.path.abspath(options.outfile_path)
        else:
            out_fpath = options.outfile_path
    else:
        # %{name}.spec as the default if not specified
        out_fpath = None

    # check the working path
    if yaml_fpath.find(os.path.sep) != -1 and os.path.dirname(yaml_fpath) != os.path.curdir:
        wdir = os.path.dirname(yaml_fpath)
        logger.info('Changing to working dir: %s' % wdir)
        os.chdir(wdir)

    yaml_fname = os.path.basename(yaml_fpath)

    # check Makefile from packaging-tools
    if not os.path.exists('Makefile'):
        logger.warning('There is no "Makefile" for this package, please update it using packaging-tools')
        if logger.ask('Need to create Makefile from default template?', False):
            mf = open('Makefile', 'w')
            mf.write(MF_TEMPLATE % os.path.basename(yaml_fname).rstrip('.yaml'))
            mf.close()

    spec_fpath, newspec = specify.generate_rpm(yaml_fname, spec_fpath=out_fpath, download_new=not options.not_download, skip_scm=options.skip_scm)
    if newspec:
        logger.warning("NEW spec file created: %s, maybe customized spec content is needed!" % spec_fpath)
    else:
        logger.info("Old spec file exists, patching %s ..." % spec_fpath)
