"""
BitBake 'Fetch' implementation for svn.

"""

# Copyright (C) 2003, 2004  Chris Larson
# Copyright (C) 2004        Marcin Juszkiewicz
#
# SPDX-License-Identifier: GPL-2.0-only
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig

import os
import sys
import logging
import bb
import re
from   bb.fetch2 import FetchMethod
from   bb.fetch2 import FetchError
from   bb.fetch2 import MissingParameterError
from   bb.fetch2 import runfetchcmd
from   bb.fetch2 import logger

class Svn(FetchMethod):
    """Class to fetch a module or modules from svn repositories"""
    def supports(self, ud, d):
        """
        Check to see if a given url can be fetched with svn.
        """
        return ud.type in ['svn']

    def urldata_init(self, ud, d):
        """
        init svn specific variable within url data
        """
        if not "module" in ud.parm:
            raise MissingParameterError('module', ud.url)

        ud.basecmd = d.getVar("FETCHCMD_svn") or "/usr/bin/env svn --non-interactive --trust-server-cert"

        ud.module = ud.parm["module"]

        if not "path_spec" in ud.parm:
            ud.path_spec = ud.module
        else:
            ud.path_spec = ud.parm["path_spec"]

        # Create paths to svn checkouts
        svndir = d.getVar("SVNDIR") or (d.getVar("DL_DIR") + "/svn")
        relpath = self._strip_leading_slashes(ud.path)
        ud.pkgdir = os.path.join(svndir, ud.host, relpath)
        ud.moddir = os.path.join(ud.pkgdir, ud.module)
        # Protects the repository from concurrent updates, e.g. from two
        # recipes fetching different revisions at the same time
        ud.svnlock = os.path.join(ud.pkgdir, "svn.lock")

        ud.setup_revisions(d)

        if 'rev' in ud.parm:
            ud.revision = ud.parm['rev']

        ud.localfile = d.expand('%s_%s_%s_%s_.tar.gz' % (ud.module.replace('/', '.'), ud.host, ud.path.replace('/', '.'), ud.revision))

    def _buildsvncommand(self, ud, d, command):
        """
        Build up an svn commandline based on ud
        command is "fetch", "update", "info"
        """

        proto = ud.parm.get('protocol', 'svn')

        svn_ssh = None
        if proto == "svn+ssh" and "ssh" in ud.parm:
            svn_ssh = ud.parm["ssh"]

        svnroot = ud.host + ud.path

        options = []

        options.append("--no-auth-cache")

        if ud.user:
            options.append("--username %s" % ud.user)

        if ud.pswd:
            options.append("--password %s" % ud.pswd)

        if command == "info":
            svncmd = "%s info %s %s://%s/%s/" % (ud.basecmd, " ".join(options), proto, svnroot, ud.module)
        elif command == "log1":
            svncmd = "%s log --limit 1 %s %s://%s/%s/" % (ud.basecmd, " ".join(options), proto, svnroot, ud.module)
        else:
            suffix = ""

            # externals may be either 'allowed' or 'nowarn', but not both.  Allowed
            # will not issue a warning, but will log to the debug buffer what has likely
            # been downloaded by SVN.
            if not ("externals" in ud.parm and ud.parm["externals"] == "allowed"):
                options.append("--ignore-externals")

            if ud.revision:
                options.append("-r %s" % ud.revision)
                suffix = "@%s" % (ud.revision)

            if command == "fetch":
                transportuser = ud.parm.get("transportuser", "")
                svncmd = "%s co %s %s://%s%s/%s%s %s" % (ud.basecmd, " ".join(options), proto, transportuser, svnroot, ud.module, suffix, ud.path_spec)
            elif command == "update":
                svncmd = "%s update %s" % (ud.basecmd, " ".join(options))
            else:
                raise FetchError("Invalid svn command %s" % command, ud.url)

        if svn_ssh:
            svncmd = "SVN_SSH=\"%s\" %s" % (svn_ssh, svncmd)

        return svncmd

    def download(self, ud, d):
        """Fetch url"""

        logger.debug(2, "Fetch: checking for module directory '" + ud.moddir + "'")

        lf = bb.utils.lockfile(ud.svnlock)

        try:
            if os.access(os.path.join(ud.moddir, '.svn'), os.R_OK):
                svnupdatecmd = self._buildsvncommand(ud, d, "update")
                logger.info("Update " + ud.url)
                # We need to attempt to run svn upgrade first in case its an older working format
                try:
                    runfetchcmd(ud.basecmd + " upgrade", d, workdir=ud.moddir)
                except FetchError:
                    pass
                logger.debug(1, "Running %s", svnupdatecmd)
                bb.fetch2.check_network_access(d, svnupdatecmd, ud.url)
                runfetchcmd(svnupdatecmd, d, workdir=ud.moddir)
            else:
                svnfetchcmd = self._buildsvncommand(ud, d, "fetch")
                logger.info("Fetch " + ud.url)
                # check out sources there
                bb.utils.mkdirhier(ud.pkgdir)
                logger.debug(1, "Running %s", svnfetchcmd)
                bb.fetch2.check_network_access(d, svnfetchcmd, ud.url)
                runfetchcmd(svnfetchcmd, d, workdir=ud.pkgdir)

            if not ("externals" in ud.parm and ud.parm["externals"] == "nowarn"):
                # Warn the user if this had externals (won't catch them all)
                output = runfetchcmd("svn propget svn:externals || true", d, workdir=ud.moddir)
                if output:
                    if "--ignore-externals" in svnfetchcmd.split():
                        bb.warn("%s contains svn:externals." % ud.url)
                        bb.warn("These should be added to the recipe SRC_URI as necessary.")
                        bb.warn("svn fetch has ignored externals:\n%s" % output)
                        bb.warn("To disable this warning add ';externals=nowarn' to the url.")
                    else:
                        bb.debug(1, "svn repository has externals:\n%s" % output)

            scmdata = ud.parm.get("scmdata", "")
            if scmdata == "keep":
                tar_flags = ""
            else:
                tar_flags = "--exclude='.svn'"

            # tar them up to a defined filename
            runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, ud.path_spec), d,
                        cleanup=[ud.localpath], workdir=ud.pkgdir)
        finally:
            bb.utils.unlockfile(lf)

    def clean(self, ud, d):
        """ Clean SVN specific files and dirs """

        bb.utils.remove(ud.localpath)
        bb.utils.remove(ud.moddir, True)
        

    def supports_srcrev(self):
        return True

    def _revision_key(self, ud, d, name):
        """
        Return a unique key for the url
        """
        return "svn:" + ud.moddir

    def _latest_revision(self, ud, d, name):
        """
        Return the latest upstream revision number
        """
        bb.fetch2.check_network_access(d, self._buildsvncommand(ud, d, "log1"), ud.url)

        output = runfetchcmd("LANG=C LC_ALL=C " + self._buildsvncommand(ud, d, "log1"), d, True)

        # skip the first line, as per output of svn log
        # then we expect the revision on the 2nd line
        revision = re.search('^r([0-9]*)', output.splitlines()[1]).group(1)

        return revision

    def sortable_revision(self, ud, d, name):
        """
        Return a sortable revision number which in our case is the revision number
        """

        return False, self._build_revision(ud, d)

    def _build_revision(self, ud, d):
        return ud.revision
