# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
 xosutil/autoversion_setup.py

 This module exports a function, setup_with_auto_version(), that will automatically generate a version.py file
 dynamically from the version option passed to the setup function. It does this without having to modify the
 source copy of version.py.

 It also automatically searches for VERSION files in the directory of the caller and its parent hierarchy, and will
 automatically load the version number from the VERSION file, if one is detected.
"""

import os
from setuptools import setup

from setuptools.command.sdist import sdist
from setuptools.command.build_py import build_py

import inspect
from autodiscover_version import autodiscover_version


class SdistCommand(sdist):
    def copy_file(self, infile, outfile, *args, **kwargs):
        if kwargs.get("dry_run"):
            return (outfile, 1)
        if os.path.split(outfile)[1] == "version.py":
            open(outfile, "w").write(
                "# do not edit. Autogenerated file.\n"
                "__version__ = '%s'\n" % self.distribution.metadata.version
            )
            return (outfile, 1)
        else:
            return sdist.copy_file(self, infile, outfile, *args, **kwargs)


class BuildPyCommand(build_py):
    def copy_file(self, infile, outfile, *args, **kwargs):
        if kwargs.get("dry_run"):
            return (outfile, 1)
        if os.path.split(outfile)[1] == "version.py":
            open(outfile, "w").write(
                "# do not edit. Autogenerated file.\n"
                "__version__ = '%s'\n" % self.distribution.metadata.version
            )
            return (outfile, 1)
        else:
            return build_py.copy_file(self, infile, outfile, *args, **kwargs)


def setup_with_auto_version(*args, **kwargs):
    # Learn the module that called this function, so we can search for any VERSION files in it.
    frame = inspect.stack()[1]
    caller_module = inspect.getmodule(frame[0])

    # Search for a VERSION file and extract the version number from it.
    version = autodiscover_version(caller_filename=caller_module.__file__)
    if version:
        kwargs["version"] = version

    cmdclass = kwargs.get("cmdclass", {}).copy()
    cmdclass.update({"sdist": SdistCommand, "build_py": BuildPyCommand})
    kwargs["cmdclass"] = cmdclass

    return setup(*args, **kwargs)
