from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools
from conans.errors import ConanInvalidConfiguration
import os
import shutil

required_conan_version = ">=1.33.0"


class LibStudXmlConan(ConanFile):
    name = "libstudxml"
    description = "A streaming XML pull parser and streaming XML serializer implementation for modern, standard C++."
    topics = ("xml", "xml-parser", "serialization")
    url = "https://github.com/conan-io/conan-center-index"
    homepage = "https://www.codesynthesis.com/projects/libstudxml/"
    license = "MIT"
    settings = "os", "compiler", "build_type", "arch"

    exports_sources = "patches/*"

    options = {
        "shared": [True, False],
        "fPIC": [True, False],
    }
    default_options = {
        "shared": False,
        "fPIC": True,
    }

    _autotools = None

    @property
    def _source_subfolder(self):
        return "source_subfolder"

    def config_options(self):
        if self.settings.os == "Windows":
            del self.options.fPIC

    def configure(self):
        if self.options.shared:
            del self.options.fPIC

    def requirements(self):
        self.requires("expat/2.4.1")

    def validate(self):
        if self.settings.compiler == "Visual Studio":
            if tools.Version(self.settings.compiler.version) < "9":
                raise ConanInvalidConfiguration("Visual Studio {} is not supported.".format(self.settings.compiler.version))

    @property
    def _settings_build(self):
        return getattr(self, "settings_build", self.settings)

    def build_requirements(self):
        if self.settings.compiler != "Visual Studio":
            self.build_requires("gnu-config/cci.20201022")
            self.build_requires("libtool/2.4.6")
            if self._settings_build.os == "Windows" and not tools.get_env("CONAN_BASH_PATH"):
                self.build_requires("msys2/cci.latest")

    def source(self):
        tools.get(**self.conan_data["sources"][self.version],
                  destination=self._source_subfolder, strip_root=True)

    def _configure_autotools(self):
        if not self._autotools:
            args = ["--with-external-expat"]
            if self.options.shared:
                args.extend(["--enable-shared", "--disable-static"])
            else:
                args.extend(["--disable-shared", "--enable-static"])

            self._autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows)
            self._autotools.configure(configure_dir=self._source_subfolder, args=args)
        return self._autotools

    def _build_vs(self):
        vc_ver = int(tools.Version(self.settings.compiler.version).major)
        sln_path = None
        def get_sln_path():
            return os.path.join(self._source_subfolder, "libstudxml-vc{}.sln".format(vc_ver))

        sln_path = get_sln_path()
        while not os.path.exists(sln_path):
            vc_ver -= 1
            sln_path = get_sln_path()

        proj_path = os.path.join(self._source_subfolder, "xml", "libstudxml-vc{}.vcxproj".format(vc_ver))

        if not self.options.shared:
            tools.replace_in_file(proj_path, "DynamicLibrary", "StaticLibrary")
            tools.replace_in_file(proj_path, "LIBSTUDXML_DYNAMIC_LIB", "LIBSTUDXML_STATIC_LIB")

        msbuild = MSBuild(self)
        msbuild.build(sln_path, platforms={"x86": "Win32"})

    @property
    def _user_info_build(self):
        return getattr(self, "user_info_build", self.deps_user_info)

    def _build_autotools(self):
        shutil.copy(self._user_info_build["gnu-config"].CONFIG_SUB,
                    os.path.join(self._source_subfolder, "config", "config.sub"))
        shutil.copy(self._user_info_build["gnu-config"].CONFIG_GUESS,
                    os.path.join(self._source_subfolder, "config", "config.guess"))

        if self.settings.compiler.get_safe("libcxx") == "libc++":
            # libc++ includes a file called 'version', and since libstudxml adds source_subfolder as an
            # include dir, libc++ ends up including their 'version' file instead, causing a compile error
            tools.remove_files_by_mask(self._source_subfolder, "version")

        with tools.chdir(self._source_subfolder):
            self.run("{} -fiv".format(tools.get_env("AUTORECONF")), win_bash=tools.os_info.is_windows)

        autotools = self._configure_autotools()
        autotools.make()

    def build(self):
        for patch in self.conan_data.get("patches", {}).get(self.version, []):
            tools.patch(**patch)

        if self.settings.compiler == "Visual Studio":
            self._build_vs()
        else:
            self._build_autotools()

    def package(self):
        self.copy(pattern="LICENSE", dst="licenses", src=self._source_subfolder)
        if self.settings.compiler == "Visual Studio":
            self.copy("xml/value-traits", dst="include", src=self._source_subfolder)
            self.copy("xml/serializer", dst="include", src=self._source_subfolder)
            self.copy("xml/qname", dst="include", src=self._source_subfolder)
            self.copy("xml/parser", dst="include", src=self._source_subfolder)
            self.copy("xml/forward", dst="include", src=self._source_subfolder)
            self.copy("xml/exception", dst="include", src=self._source_subfolder)
            self.copy("xml/content", dst="include", src=self._source_subfolder)
            self.copy("xml/*.ixx", dst="include", src=self._source_subfolder)
            self.copy("xml/*.txx", dst="include", src=self._source_subfolder)
            self.copy("xml/*.hxx", dst="include", src=self._source_subfolder)
            self.copy("xml/*.h", dst="include", src=self._source_subfolder)

            suffix = ""
            if self.settings.arch == "x86_64":
                suffix = "64"
            if self.options.shared:
                self.copy("*.lib", dst="lib", src=os.path.join(self._source_subfolder, "lib" + suffix))
                self.copy("*.dll", dst="bin", src=os.path.join(self._source_subfolder, "bin" + suffix))
            else:
                self.copy("*.lib", dst="lib", src=os.path.join(self._source_subfolder, "bin" + suffix))
        else:
            autotools = self._configure_autotools()
            autotools.install()
            tools.remove_files_by_mask(os.path.join(self.package_folder, "lib"), "libstudxml.la")
            tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
            tools.rmdir(os.path.join(self.package_folder, "share"))

    def package_info(self):
        self.cpp_info.libs = tools.collect_libs(self)
        self.cpp_info.names["pkg_config"] = "libstudxml"

        # If built with makefile, static library mechanism is provided by their buildsystem already
        if self.settings.compiler == "Visual Studio" and not self.options.shared:
            self.cpp_info.defines = ["LIBSTUDXML_STATIC_LIB=1"]

[((63, 8, 64, 70), 'conans.tools.get', 'tools.get', (), '', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((95, 18, 95, 31), 'conans.MSBuild', 'MSBuild', ({(95, 26, 95, 30): 'self'}, {}), '(self)', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((159, 29, 159, 53), 'conans.tools.collect_libs', 'tools.collect_libs', ({(159, 48, 159, 52): 'self'}, {}), '(self)', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((74, 30, 74, 96), 'conans.AutoToolsBuildEnvironment', 'AutoToolsBuildEnvironment', (), '', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((85, 18, 85, 42), 'os.path.exists', 'os.path.exists', ({(85, 33, 85, 41): 'sln_path'}, {}), '(sln_path)', False, 'import os\n'), ((92, 12, 92, 79), 'conans.tools.replace_in_file', 'tools.replace_in_file', ({(92, 34, 92, 43): 'proj_path', (92, 45, 92, 61): '"""DynamicLibrary"""', (92, 63, 92, 78): '"""StaticLibrary"""'}, {}), "(proj_path, 'DynamicLibrary', 'StaticLibrary')", False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((93, 12, 93, 95), 'conans.tools.replace_in_file', 'tools.replace_in_file', ({(93, 34, 93, 43): 'proj_path', (93, 45, 93, 69): '"""LIBSTUDXML_DYNAMIC_LIB"""', (93, 71, 93, 94): '"""LIBSTUDXML_STATIC_LIB"""'}, {}), "(proj_path, 'LIBSTUDXML_DYNAMIC_LIB',\n    'LIBSTUDXML_STATIC_LIB')", False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((104, 20, 104, 80), 'os.path.join', 'os.path.join', ({(104, 33, 104, 55): 'self._source_subfolder', (104, 57, 104, 65): '"""config"""', (104, 67, 104, 79): '"""config.sub"""'}, {}), "(self._source_subfolder, 'config', 'config.sub')", False, 'import os\n'), ((106, 20, 106, 82), 'os.path.join', 'os.path.join', ({(106, 33, 106, 55): 'self._source_subfolder', (106, 57, 106, 65): '"""config"""', (106, 67, 106, 81): '"""config.guess"""'}, {}), "(self._source_subfolder, 'config', 'config.guess')", False, 'import os\n'), ((111, 12, 111, 73), 'conans.tools.remove_files_by_mask', 'tools.remove_files_by_mask', ({(111, 39, 111, 61): 'self._source_subfolder', (111, 63, 111, 72): '"""version"""'}, {}), "(self._source_subfolder, 'version')", False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((113, 13, 113, 48), 'conans.tools.chdir', 'tools.chdir', ({(113, 25, 113, 47): 'self._source_subfolder'}, {}), '(self._source_subfolder)', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((121, 12, 121, 32), 'conans.tools.patch', 'tools.patch', ({}, {}), '(**patch)', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((48, 15, 48, 60), 'conans.tools.Version', 'tools.Version', ({(48, 29, 48, 59): 'self.settings.compiler.version'}, {}), '(self.settings.compiler.version)', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((79, 21, 79, 66), 'conans.tools.Version', 'tools.Version', ({(79, 35, 79, 65): 'self.settings.compiler.version'}, {}), '(self.settings.compiler.version)', False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((154, 39, 154, 79), 'os.path.join', 'os.path.join', ({(154, 52, 154, 71): 'self.package_folder', (154, 73, 154, 78): '"""lib"""'}, {}), "(self.package_folder, 'lib')", False, 'import os\n'), ((155, 24, 155, 77), 'os.path.join', 'os.path.join', ({(155, 37, 155, 56): 'self.package_folder', (155, 58, 155, 63): '"""lib"""', (155, 65, 155, 76): '"""pkgconfig"""'}, {}), "(self.package_folder, 'lib', 'pkgconfig')", False, 'import os\n'), ((156, 24, 156, 66), 'os.path.join', 'os.path.join', ({(156, 37, 156, 56): 'self.package_folder', (156, 58, 156, 65): '"""share"""'}, {}), "(self.package_folder, 'share')", False, 'import os\n'), ((59, 60, 59, 92), 'conans.tools.get_env', 'tools.get_env', ({(59, 74, 59, 91): '"""CONAN_BASH_PATH"""'}, {}), "('CONAN_BASH_PATH')", False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((114, 38, 114, 65), 'conans.tools.get_env', 'tools.get_env', ({(114, 52, 114, 64): '"""AUTORECONF"""'}, {}), "('AUTORECONF')", False, 'from conans import ConanFile, AutoToolsBuildEnvironment, MSBuild, tools\n'), ((147, 50, 147, 102), 'os.path.join', 'os.path.join', ({(147, 63, 147, 85): 'self._source_subfolder', (147, 87, 147, 101): "('lib' + suffix)"}, {}), "(self._source_subfolder, 'lib' + suffix)", False, 'import os\n'), ((148, 50, 148, 102), 'os.path.join', 'os.path.join', ({(148, 63, 148, 85): 'self._source_subfolder', (148, 87, 148, 101): "('bin' + suffix)"}, {}), "(self._source_subfolder, 'bin' + suffix)", False, 'import os\n'), ((150, 50, 150, 102), 'os.path.join', 'os.path.join', ({(150, 63, 150, 85): 'self._source_subfolder', (150, 87, 150, 101): "('bin' + suffix)"}, {}), "(self._source_subfolder, 'bin' + suffix)", False, 'import os\n')]