"""
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", 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
