# Script utility functions
#
# Copyright (C) 2014 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import sys
import os
import logging
import glob
import argparse
import subprocess
import tempfile
import shutil

def logger_create(name, stream=None):
    logger = logging.getLogger(name)
    loggerhandler = logging.StreamHandler(stream=stream)
    loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
    logger.addHandler(loggerhandler)
    logger.setLevel(logging.INFO)
    return logger

def logger_setup_color(logger, color='auto'):
    from bb.msg import BBLogFormatter
    console = logging.StreamHandler(sys.stdout)
    formatter = BBLogFormatter("%(levelname)s: %(message)s")
    console.setFormatter(formatter)
    logger.handlers = [console]
    if color == 'always' or (color=='auto' and console.stream.isatty()):
        formatter.enable_color()


def load_plugins(logger, plugins, pluginpath):
    import imp

    def load_plugin(name):
        logger.debug('Loading plugin %s' % name)
        fp, pathname, description = imp.find_module(name, [pluginpath])
        try:
            return imp.load_module(name, fp, pathname, description)
        finally:
            if fp:
                fp.close()

    def plugin_name(filename):
        return os.path.splitext(os.path.basename(filename))[0]

    known_plugins = [plugin_name(p.__name__) for p in plugins]
    logger.debug('Loading plugins from %s...' % pluginpath)
    for fn in glob.glob(os.path.join(pluginpath, '*.py')):
        name = plugin_name(fn)
        if name != '__init__' and name not in known_plugins:
            plugin = load_plugin(name)
            if hasattr(plugin, 'plugin_init'):
                plugin.plugin_init(plugins)
            plugins.append(plugin)

def git_convert_standalone_clone(repodir):
    """If specified directory is a git repository, ensure it's a standalone clone"""
    import bb.process
    if os.path.exists(os.path.join(repodir, '.git')):
        alternatesfile = os.path.join(repodir, '.git', 'objects', 'info', 'alternates')
        if os.path.exists(alternatesfile):
            # This will have been cloned with -s, so we need to convert it so none
            # of the contents is shared
            bb.process.run('git repack -a', cwd=repodir)
            os.remove(alternatesfile)

def fetch_uri(d, uri, destdir, srcrev=None):
    """Fetch a URI to a local directory"""
    import bb
    tmpparent = d.getVar('BASE_WORKDIR')
    bb.utils.mkdirhier(tmpparent)
    tmpworkdir = tempfile.mkdtemp(dir=tmpparent)
    try:
        bb.utils.mkdirhier(destdir)
        localdata = bb.data.createCopy(d)

        # Set some values to allow extend_recipe_sysroot to work here we're we are not running from a task
        localdata.setVar('WORKDIR', tmpworkdir)
        localdata.setVar('BB_RUNTASK', 'do_fetch')
        localdata.setVar('PN', 'dummy')
        localdata.setVar('BB_LIMITEDDEPS', '1')
        bb.build.exec_func("extend_recipe_sysroot", localdata)

        # Set some values for the benefit of the fetcher code
        localdata.setVar('BB_STRICT_CHECKSUM', '')
        localdata.setVar('SRCREV', srcrev)
        ret = (None, None)
        olddir = os.getcwd()
        try:
            fetcher = bb.fetch2.Fetch([uri], localdata)
            for u in fetcher.ud:
                ud = fetcher.ud[u]
                ud.ignore_checksums = True
            fetcher.download()
            for u in fetcher.ud:
                ud = fetcher.ud[u]
                if ud.localpath.rstrip(os.sep) == localdata.getVar('DL_DIR').rstrip(os.sep):
                    raise Exception('Local path is download directory - please check that the URI "%s" is correct' % uri)
            fetcher.unpack(destdir)
            for u in fetcher.ud:
                ud = fetcher.ud[u]
                if ud.method.recommends_checksum(ud):
                    md5value = bb.utils.md5_file(ud.localpath)
                    sha256value = bb.utils.sha256_file(ud.localpath)
                    ret = (md5value, sha256value)
        finally:
            os.chdir(olddir)
    finally:
        shutil.rmtree(tmpworkdir)
    return ret

def run_editor(fn):
    if isinstance(fn, str):
        params = '"%s"' % fn
    else:
        params = ''
        for fnitem in fn:
            params += ' "%s"' % fnitem

    editor = os.getenv('VISUAL', os.getenv('EDITOR', 'vi'))
    try:
        return subprocess.check_call('%s %s' % (editor, params), shell=True)
    except OSError as exc:
        logger.error("Execution of editor '%s' failed: %s", editor, exc)
        return 1

def is_src_url(param):
    """
    Check if a parameter is a URL and return True if so
    NOTE: be careful about changing this as it will influence how devtool/recipetool command line handling works
    """
    if not param:
        return False
    elif '://' in param:
        return True
    elif param.startswith('git@') or ('@' in param and param.endswith('.git')):
        return True
    return False