import os, subprocess

from . import mlog
from .mesonlib import Popen_safe
from .wrap.wrap import API_ROOT, PackageDefinition, Resolver, WrapException
from .wrap import wraptool

def update_wrapdb_file(wrap, repo_dir, options):
    patch_url = wrap.get('patch_url')
    branch, revision = wraptool.parse_patch_url(patch_url)
    new_branch, new_revision = wraptool.get_latest_version(wrap.name)
    if new_branch == branch and new_revision == revision:
        mlog.log('  -> Up to date.')
        return
    wraptool.update_wrap_file(wrap.filename, wrap.name, new_branch, new_revision)
    msg = ['  -> New wrap file downloaded.']
    # Meson reconfigure won't use the new wrap file as long as the source
    # directory exists. We don't delete it ourself to avoid data loss in case
    # user has changes in their copy.
    if os.path.isdir(repo_dir):
        msg += ['To use it, delete', mlog.bold(repo_dir), 'and run', mlog.bold('meson --reconfigure')]
    mlog.log(*msg)

def update_file(wrap, repo_dir, options):
    patch_url = wrap.values.get('patch_url', '')
    if patch_url.startswith(API_ROOT):
        update_wrapdb_file(wrap, repo_dir, options)
    elif not os.path.isdir(repo_dir):
        # The subproject is not needed, or it is a tarball extracted in
        # 'libfoo-1.0' directory and the version has been bumped and the new
        # directory is 'libfoo-2.0'. In that case forcing a meson
        # reconfigure will download and use the new tarball.
        mlog.log('  -> Subproject has not been checked out. Run', mlog.bold('meson --reconfigure'), 'to fetch it if needed.')
    else:
        # The subproject has not changed, or the new source and/or patch
        # tarballs should be extracted in the same directory than previous
        # version.
        mlog.log('  -> Subproject has not changed, or the new source/patch needs to be extracted on the same location.\n' +
                 '     In that case, delete', mlog.bold(repo_dir), 'and run', mlog.bold('meson --reconfigure'))

def git(cmd, workingdir):
    return subprocess.check_output(['git', '-C', workingdir] + cmd,
                                   stderr=subprocess.STDOUT).decode()

def git_show(repo_dir):
    commit_message = git(['show', '--quiet', '--pretty=format:%h%n%d%n%s%n[%an]'], repo_dir)
    parts = [s.strip() for s in commit_message.split('\n')]
    mlog.log('  ->', mlog.yellow(parts[0]), mlog.red(parts[1]), parts[2], mlog.blue(parts[3]))

def update_git(wrap, repo_dir, options):
    if not os.path.isdir(repo_dir):
        mlog.log('  -> Not used.')
        return
    revision = wrap.get('revision')
    ret = git(['rev-parse', '--abbrev-ref', 'HEAD'], repo_dir).strip()
    if ret == 'HEAD':
        try:
            # We are currently in detached mode, just checkout the new revision
            git(['fetch'], repo_dir)
            git(['checkout', revision], repo_dir)
        except subprocess.CalledProcessError as e:
            out = e.output.decode().strip()
            mlog.log('  -> Could not checkout revision', mlog.cyan(revision))
            mlog.log(mlog.red(out))
            mlog.log(mlog.red(str(e)))
            return
    elif ret == revision:
        try:
            # We are in the same branch, pull latest commits
            git(['-c', 'rebase.autoStash=true', 'pull', '--rebase'], repo_dir)
        except subprocess.CalledProcessError as e:
            out = e.output.decode().strip()
            mlog.log('  -> Could not rebase', mlog.bold(repo_dir), 'please fix and try again.')
            mlog.log(mlog.red(out))
            mlog.log(mlog.red(str(e)))
            return
    else:
        # We are in another branch, probably user created their own branch and
        # we should rebase it on top of wrap's branch.
        if options.rebase:
            try:
                git(['fetch'], repo_dir)
                git(['-c', 'rebase.autoStash=true', 'rebase', revision], repo_dir)
            except subprocess.CalledProcessError as e:
                out = e.output.decode().strip()
                mlog.log('  -> Could not rebase', mlog.bold(repo_dir), 'please fix and try again.')
                mlog.log(mlog.red(out))
                mlog.log(mlog.red(str(e)))
                return
        else:
            mlog.log('  -> Target revision is', mlog.bold(revision), 'but currently in branch is', mlog.bold(ret), '\n' +
                     '     To rebase your branch on top of', mlog.bold(revision), 'use', mlog.bold('--rebase'), 'option.')
            return

    git(['submodule', 'update'], repo_dir)
    git_show(repo_dir)

def update_hg(wrap, repo_dir, options):
    if not os.path.isdir(repo_dir):
        mlog.log('  -> Not used.')
        return
    revno = wrap.get('revision')
    if revno.lower() == 'tip':
        # Failure to do pull is not a fatal error,
        # because otherwise you can't develop without
        # a working net connection.
        subprocess.call(['hg', 'pull'], cwd=repo_dir)
    else:
        if subprocess.call(['hg', 'checkout', revno], cwd=repo_dir) != 0:
            subprocess.check_call(['hg', 'pull'], cwd=repo_dir)
            subprocess.check_call(['hg', 'checkout', revno], cwd=repo_dir)

def update_svn(wrap, repo_dir, options):
    if not os.path.isdir(repo_dir):
        mlog.log('  -> Not used.')
        return
    revno = wrap.get('revision')
    p, out = Popen_safe(['svn', 'info', '--show-item', 'revision', repo_dir])
    current_revno = out
    if current_revno == revno:
        return
    if revno.lower() == 'head':
        # Failure to do pull is not a fatal error,
        # because otherwise you can't develop without
        # a working net connection.
        subprocess.call(['svn', 'update'], cwd=repo_dir)
    else:
        subprocess.check_call(['svn', 'update', '-r', revno], cwd=repo_dir)

def update(wrap, repo_dir, options):
    mlog.log('Updating %s...' % wrap.name)
    if wrap.type == 'file':
        update_file(wrap, repo_dir, options)
    elif wrap.type == 'git':
        update_git(wrap, repo_dir, options)
    elif wrap.type == 'hg':
        update_hg(wrap, repo_dir, options)
    elif wrap.type == 'svn':
        update_svn(wrap, repo_dir, options)
    else:
        mlog.log('  -> Cannot update', wrap.type, 'subproject')

def checkout(wrap, repo_dir, options):
    if wrap.type != 'git' or not os.path.isdir(repo_dir):
        return
    branch_name = options.branch_name if options.branch_name else wrap.get('revision')
    cmd = ['checkout', branch_name, '--']
    if options.b:
        cmd.insert(1, '-b')
    mlog.log('Checkout %s in %s...' % (branch_name, wrap.name))
    try:
        git(cmd, repo_dir)
        git_show(repo_dir)
    except subprocess.CalledProcessError as e:
        out = e.output.decode().strip()
        mlog.log('  -> ', mlog.red(out))

def download(wrap, repo_dir, options):
    mlog.log('Download %s...' % wrap.name)
    if os.path.isdir(repo_dir):
        mlog.log('  -> Already downloaded')
        return
    try:
        r = Resolver(os.path.dirname(repo_dir))
        r.resolve(wrap.name)
        mlog.log('  -> done')
    except WrapException as e:
        mlog.log('  ->', mlog.red(str(e)))

def add_common_arguments(p):
    p.add_argument('--sourcedir', default='.',
                   help='Path to source directory')
    p.add_argument('subprojects', nargs='*',
                   help='List of subprojects (default: all)')

def add_arguments(parser):
    subparsers = parser.add_subparsers(title='Commands', dest='command')
    subparsers.required = True

    p = subparsers.add_parser('update', help='Update all subprojects from wrap files')
    p.add_argument('--rebase', default=False, action='store_true',
                   help='Rebase your branch on top of wrap\'s revision (git only)')
    add_common_arguments(p)
    p.set_defaults(subprojects_func=update)

    p = subparsers.add_parser('checkout', help='Checkout a branch (git only)')
    p.add_argument('-b', default=False, action='store_true',
                   help='Create a new branch')
    p.add_argument('branch_name', nargs='?',
                   help='Name of the branch to checkout or create (default: revision set in wrap file)')
    add_common_arguments(p)
    p.set_defaults(subprojects_func=checkout)

    p = subparsers.add_parser('download', help='Ensure subprojects are fetched, even if not in use. ' +
                                               'Already downloaded subprojects are not modified. ' +
                                               'This can be used to pre-fetch all subprojects and avoid downloads during configure.')
    add_common_arguments(p)
    p.set_defaults(subprojects_func=download)

def run(options):
    src_dir = os.path.relpath(os.path.realpath(options.sourcedir))
    if not os.path.isfile(os.path.join(src_dir, 'meson.build')):
        mlog.error('Directory', mlog.bold(src_dir), 'does not seem to be a Meson source directory.')
        return 1
    subprojects_dir = os.path.join(src_dir, 'subprojects')
    if not os.path.isdir(subprojects_dir):
        mlog.log('Directory', mlog.bold(src_dir), 'does not seem to have subprojects.')
        return 0
    files = []
    for name in options.subprojects:
        f = os.path.join(subprojects_dir, name + '.wrap')
        if not os.path.isfile(f):
            mlog.error('Subproject', mlog.bold(name), 'not found.')
            return 1
        else:
            files.append(f)
    if not files:
        for f in os.listdir(subprojects_dir):
            if f.endswith('.wrap'):
                files.append(os.path.join(subprojects_dir, f))
    for f in files:
        wrap = PackageDefinition(f)
        directory = wrap.values.get('directory', wrap.name)
        repo_dir = os.path.join(subprojects_dir, directory)
        options.subprojects_func(wrap, repo_dir, options)
    return 0
