# Copyright (c) 2018 Open Source Foundries Limited.
#
# SPDX-License-Identifier: Apache-2.0
'''Common definitions for building Zephyr applications with CMake.

This provides some default settings and convenience wrappers for
building Zephyr applications needed by multiple commands.

See build.py for the build command itself.
'''

from collections import OrderedDict
import os.path
import re
import subprocess
import shutil
import sys

import packaging.version
from west import log
from west.util import quote_sh_list

DEFAULT_CACHE = 'CMakeCache.txt'

DEFAULT_CMAKE_GENERATOR = 'Ninja'
'''Name of the default CMake generator.'''


def run_cmake(args, cwd=None, capture_output=False, dry_run=False):
    '''Run cmake to (re)generate a build system, a script, etc.

    :param args: arguments to pass to CMake
    :param cwd: directory to run CMake in, cwd is default
    :param capture_output: if True, the output is returned instead of being
                           displayed (None is returned by default, or if
                           dry_run is also True)
    :param dry_run: don't actually execute the command, just print what
                    would have been run

    If capture_output is set to True, returns the output of the command instead
    of displaying it on stdout/stderr..'''
    cmake = shutil.which('cmake')
    if cmake is None and not dry_run:
        log.die('CMake is not installed or cannot be found; cannot build.')
    _ensure_min_version(cmake, dry_run)

    cmd = [cmake] + args

    kwargs = dict()
    if capture_output:
        kwargs['stdout'] = subprocess.PIPE
        # CMake sends the output of message() to stderr unless it's STATUS
        kwargs['stderr'] = subprocess.STDOUT
    if cwd:
        kwargs['cwd'] = cwd

    if dry_run:
        in_cwd = ' (in {})'.format(cwd) if cwd else ''
        log.inf('Dry run{}:'.format(in_cwd), quote_sh_list(cmd))
        return None

    log.dbg('Running CMake:', quote_sh_list(cmd), level=log.VERBOSE_NORMAL)
    p = subprocess.Popen(cmd, **kwargs)
    out, _ = p.communicate()
    if p.returncode == 0:
        if out:
            return out.decode(sys.getdefaultencoding()).splitlines()
        else:
            return None
    else:
        # A real error occurred, raise an exception
        raise subprocess.CalledProcessError(p.returncode, p.args)


def run_build(build_directory, **kwargs):
    '''Run cmake in build tool mode.

    :param build_directory: runs "cmake --build build_directory"
    :param extra_args: optional kwarg. List of additional CMake arguments;
                       these come after "--build <build_directory>"
                       on the command line.

    Any additional keyword arguments are passed as-is to run_cmake().
    '''
    extra_args = kwargs.pop('extra_args', [])
    return run_cmake(['--build', build_directory] + extra_args, **kwargs)


def make_c_identifier(string):
    '''Make a C identifier from a string in the same way CMake does.
    '''
    # The behavior of CMake's string(MAKE_C_IDENTIFIER ...)  is not
    # precisely documented. This behavior matches the test case
    # that introduced the function:
    #
    # https://gitlab.kitware.com/cmake/cmake/commit/0ab50aea4c4d7099b339fb38b4459d0debbdbd85
    ret = []

    alpha_under = re.compile('[A-Za-z_]')
    alpha_num_under = re.compile('[A-Za-z0-9_]')

    if not alpha_under.match(string):
        ret.append('_')
    for c in string:
        if alpha_num_under.match(c):
            ret.append(c)
        else:
            ret.append('_')

    return ''.join(ret)


class CMakeCacheEntry:
    '''Represents a CMake cache entry.

    This class understands the type system in a CMakeCache.txt, and
    converts the following cache types to Python types:

    Cache Type    Python type
    ----------    -------------------------------------------
    FILEPATH      str
    PATH          str
    STRING        str OR list of str (if ';' is in the value)
    BOOL          bool
    INTERNAL      str OR list of str (if ';' is in the value)
    STATIC        str OR list of str (if ';' is in the value)
    ----------    -------------------------------------------
    '''

    # Regular expression for a cache entry.
    #
    # CMake variable names can include escape characters, allowing a
    # wider set of names than is easy to match with a regular
    # expression. To be permissive here, use a non-greedy match up to
    # the first colon (':'). This breaks if the variable name has a
    # colon inside, but it's good enough.
    CACHE_ENTRY = re.compile(
        r'''(?P<name>.*?)                                      # name
         :(?P<type>FILEPATH|PATH|STRING|BOOL|INTERNAL|STATIC)  # type
         =(?P<value>.*)                                        # value
        ''', re.X)

    @classmethod
    def _to_bool(cls, val):
        # Convert a CMake BOOL string into a Python bool.
        #
        #   "True if the constant is 1, ON, YES, TRUE, Y, or a
        #   non-zero number. False if the constant is 0, OFF, NO,
        #   FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in
        #   the suffix -NOTFOUND. Named boolean constants are
        #   case-insensitive. If the argument is not one of these
        #   constants, it is treated as a variable."
        #
        # https://cmake.org/cmake/help/v3.0/command/if.html
        val = val.upper()
        if val in ('ON', 'YES', 'TRUE', 'Y'):
            return True
        elif val in ('OFF', 'NO', 'FALSE', 'N', 'IGNORE', 'NOTFOUND', ''):
            return False
        elif val.endswith('-NOTFOUND'):
            return False
        else:
            try:
                v = int(val)
                return v != 0
            except ValueError as exc:
                raise ValueError('invalid bool {}'.format(val)) from exc

    @classmethod
    def from_line(cls, line, line_no):
        # Comments can only occur at the beginning of a line.
        # (The value of an entry could contain a comment character).
        if line.startswith('//') or line.startswith('#'):
            return None

        # Whitespace-only lines do not contain cache entries.
        if not line.strip():
            return None

        m = cls.CACHE_ENTRY.match(line)
        if not m:
            return None

        name, type_, value = (m.group(g) for g in ('name', 'type', 'value'))
        if type_ == 'BOOL':
            try:
                value = cls._to_bool(value)
            except ValueError as exc:
                args = exc.args + ('on line {}: {}'.format(line_no, line),)
                raise ValueError(args) from exc
        elif type_ in {'STRING', 'INTERNAL', 'STATIC'}:
            # If the value is a CMake list (i.e. is a string which
            # contains a ';'), convert to a Python list.
            if ';' in value:
                value = value.split(';')

        return CMakeCacheEntry(name, value)

    def __init__(self, name, value):
        self.name = name
        self.value = value

    def __str__(self):
        fmt = 'CMakeCacheEntry(name={}, value={})'
        return fmt.format(self.name, self.value)


class CMakeCache:
    '''Parses and represents a CMake cache file.'''

    @staticmethod
    def from_build_dir(build_dir):
        return CMakeCache(os.path.join(build_dir, DEFAULT_CACHE))

    def __init__(self, cache_file):
        self.cache_file = cache_file
        self.load(cache_file)

    def load(self, cache_file):
        entries = []
        with open(cache_file, 'r', encoding="utf-8") as cache:
            for line_no, line in enumerate(cache):
                entry = CMakeCacheEntry.from_line(line, line_no)
                if entry:
                    entries.append(entry)
        self._entries = OrderedDict((e.name, e) for e in entries)

    def get(self, name, default=None):
        entry = self._entries.get(name)
        if entry is not None:
            return entry.value
        else:
            return default

    def get_list(self, name, default=None):
        if default is None:
            default = []
        entry = self._entries.get(name)
        if entry is not None:
            value = entry.value
            if isinstance(value, list):
                return value
            elif isinstance(value, str):
                return [value] if value else []
            else:
                msg = 'invalid value {} type {}'
                raise RuntimeError(msg.format(value, type(value)))
        else:
            return default

    def __contains__(self, name):
        return name in self._entries

    def __getitem__(self, name):
        return self._entries[name].value

    def __setitem__(self, name, entry):
        if not isinstance(entry, CMakeCacheEntry):
            msg = 'improper type {} for value {}, expecting CMakeCacheEntry'
            raise TypeError(msg.format(type(entry), entry))
        self._entries[name] = entry

    def __delitem__(self, name):
        del self._entries[name]

    def __iter__(self):
        return iter(self._entries.values())

def _ensure_min_version(cmake, dry_run):
    cmd = [cmake, '--version']
    if dry_run:
        log.inf('Dry run:', quote_sh_list(cmd))
        return

    try:
        version_out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
    except subprocess.CalledProcessError as cpe:
        log.die('cannot get cmake version:', str(cpe))
    decoded = version_out.decode('utf-8')
    lines = decoded.splitlines()
    if not lines:
        log.die('can\'t get cmake version: ' +
                'unexpected "cmake --version" output:\n{}\n'.
                format(decoded) +
                'Please install CMake ' + _MIN_CMAKE_VERSION_STR +
                ' or higher (https://cmake.org/download/).')
    version = lines[0].split()[2]
    if '-' in version:
        # Handle semver cases like "3.19.20210206-g1e50ab6"
        # which Kitware uses for prerelease versions.
        version = version.split('-', 1)[0]
    if packaging.version.parse(version) < _MIN_CMAKE_VERSION:
        log.die('cmake version', version,
                'is less than minimum version {};'.
                format(_MIN_CMAKE_VERSION_STR),
                'please update your CMake (https://cmake.org/download/).')
    else:
        log.dbg('cmake version', version, 'is OK; minimum version is',
                _MIN_CMAKE_VERSION_STR)

_MIN_CMAKE_VERSION_STR = '3.13.1'
_MIN_CMAKE_VERSION = packaging.version.parse(_MIN_CMAKE_VERSION_STR)
