#!/bin/sh
''''[ ! -z $VIRTUAL_ENV ] && exec python -u -- "$0" ${1+"$@"}; command -v python3 > /dev/null && exec python3 -u -- "$0" ${1+"$@"}; exec python2 -u -- "$0" ${1+"$@"} # '''

import sys
import os
import argparse
import shutil
import tempfile
import traceback

HERE = os.path.dirname(__file__)
READIES = os.path.abspath(os.path.join(HERE, ".."))
sys.path.insert(0, READIES)
import paella  # noqa: F401

os.environ["PYTHONWARNINGS"] = 'ignore:DEPRECATION::pip._internal.cli.base_command'

#----------------------------------------------------------------------------------------------

CMAKE_VER='3.22.2'

#----------------------------------------------------------------------------------------------

class CMakeSetupFromRepo(paella.Setup):
    def __init__(self, args):
        paella.Setup.__init__(self, nop=args.nop)

    def common_first(self):
        pass

    def debian_compat(self):
        self.install("cmake")

    def redhat_compat(self):
        self.run("%s/bin/getepel" % READIES, sudo=True)
        if self.dist in ['centos', 'ol'] and self.os_version[0] == 8:
            # cmake: symbol lookup error: cmake: undefined symbol: archive_write_add_filter_zstd
            self.run("dnf update -y libarchive", sudo=True)
            self.install("cmake")
        else:
            self.install("cmake3")
            self.run("ln -sf `command -v cmake` /usr/local/bin/cmake", sudo=True)
            self.run("ln -sf `command -v ctest` /usr/local/bin/ctest", sudo=True)
            self.run("ln -sf `command -v cpack` /usr/local/bin/cpack", sudo=True)

    def alpine(self):
        self.install("cmake")

    def fedora(self):
        self.redhat_compat()

    def macos(self):
        self.install("cmake")
        base_dir = paella.sh("brew --prefix")
        ver = paella.sh("brew ls --versions cmake | head -1 | awk '{print $2}'").strip()
        dir = "{base_dir}/Cellar/cmake/{ver}//bin".format(base_dir=base_dir, ver=ver)
        self.run("ln -sf {dir}/cmake /usr/local/bin/cmake".format(dir=dir), sudo=True)
        self.run("ln -sf {dir}/ctest /usr/local/bin/ctest".format(dir=dir), sudo=True)
        self.run("ln -sf {dir}/cpack /usr/local/bin/cpack".format(dir=dir), sudo=True)

    def common_last(self):
        verstr = paella.sh("cmake --version | head -1 | awk '{print $3}'").strip()
        if verstr == '':
            return
        ver = int(verstr.split('.')[0])
        if ver >= 3:
            print("# installed cmake " + verstr)
            sys.exit(0)
        self.uninstall("cmake", output=False)

#----------------------------------------------------------------------------------------------

class CMakeSetup(paella.Setup):
    def __init__(self, args):
        paella.Setup.__init__(self, nop=args.nop)
        # check whether it is possible to download a pre-built cmake
        self.build = args.build or not (self.os == 'linux' and (self.arch == 'x64' or self.platform.is_arm64()))
        self.prefix = '/usr' if args.usr else '/usr/local'

    def common_first(self):
        self.install_downloaders()
        if self.build:
            self.install("unzip")
            self.run("%s/bin/getgcc" % READIES)

    def debian_compat(self):
        if self.build:
            self.install("libssl-dev")

    def redhat_compat(self):
        if self.build:
            self.install("openssl-devel")

    def fedora(self):
        self.redhat_compat()

    def macos(self):
        pass

    def linux_last(self):
        if self.platform.is_arm64():
            url = "https://github.com/Kitware/CMake/releases/download/v{CMAKE_VER}/cmake-{CMAKE_VER}-linux-aarch64.sh".format(CMAKE_VER=CMAKE_VER)
        else:
            url="https://github.com/Kitware/CMake/releases/download/v{CMAKE_VER}/cmake-{CMAKE_VER}-`uname`-`uname -m`.sh".format(CMAKE_VER=CMAKE_VER)
        if not self.build:
            dir = tempfile.mkdtemp(prefix='cmake.')
            self.run(r"""
                wget -q -O {DIR}/cmake.sh {URL}
                sh {DIR}/cmake.sh --skip-license --prefix={PREFIX}
                rm -rf {DIR}
                """.format(DIR=dir, URL=url, PREFIX=self.prefix), sudo=True)
            if args.usr and os.path.exists("/usr/local/bin/cmake"):
                self.run("cd /usr/local/bin; rm -f cmake cmake-gui ctest cpack ccmake", sudo="file")

    def common_last(self):
        if self.build:
            dir = tempfile.mkdtemp(prefix='cmake.')
            self.run(r"""
                cd {DIR}
                wget -q -O cmake.zip https://github.com/Kitware/CMake/archive/v{CMAKE_VER}.zip
                unzip -q cmake.zip
                cd CMake-{CMAKE_VER}/
                ./bootstrap --parallel=`nproc`
                make -j`nproc`
                """.format(DIR=dir, CMAKE_VER=CMAKE_VER))
            self.run(r"""
                make -C {DIR} install
                rm -rf {DIR}
                """.format(DIR=dir), sudo=True)

#----------------------------------------------------------------------------------------------

parser = argparse.ArgumentParser(description='Install CMake')
parser.add_argument('-n', '--nop', action="store_true", help='no operation')
parser.add_argument('--from-repo', action="store_true", help='install from distribution repository')
parser.add_argument('--build', action="store_true", help='build from source')
parser.add_argument('--usr', action="store_true", help='install into /usr instead of into /usr/local')
args = parser.parse_args()

try:
    platform = paella.Platform()
    if args.from_repo and not args.build or platform.os == 'macos':
        CMakeSetupFromRepo(args).setup()
    CMakeSetup(args).setup()
except Exception as x:
    traceback.print_exc()
    fatal(str(x))

exit(0)
