#!/usr/bin/env python3
# Copyright 2019 The Pigweed Authors
#
# 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
#
#     https://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.
"""Checks if the environment is set up correctly for Pigweed."""

import argparse
import logging
import json
import os
import shutil
import subprocess
import sys
import tempfile


def call_stdout(*args, **kwargs):
    kwargs.update(stdout=subprocess.PIPE)
    proc = subprocess.run(*args, **kwargs)
    return proc.stdout.decode('utf-8')


class _Fatal(Exception):
    pass


class DoctorContext:
    """Base class for other checks."""
    def __init__(self, *, strict=False, log=None):
        self.name = self.__class__.__name__
        self._strict = strict
        self._log = log or logging.getLogger(__name__)
        self.failures = set()
        self.curr_checker = None

    def fatal(self, fmt, *args, **kwargs):
        """Same as error() but terminates the checkearly."""
        self.error(fmt, *args, **kwargs)
        raise _Fatal()

    def error(self, fmt, *args, **kwargs):
        self._log.error(fmt, *args, **kwargs)
        self.failures.add(self.curr_checker)

    def warning(self, fmt, *args, **kwargs):
        if self._strict:
            self.error(fmt, *args, **kwargs)
        else:
            self._log.warning(fmt, *args, **kwargs)

    def info(self, fmt, *args, **kwargs):
        self._log.info(fmt, *args, **kwargs)

    def debug(self, fmt, *args, **kwargs):
        self._log.debug(fmt, *args, **kwargs)


def register_into(dest):
    def decorate(func):
        dest.append(func)
        return func

    return decorate


CHECKS = []


@register_into(CHECKS)
def pw_root(ctx: DoctorContext):
    """Check that environment variable PW_ROOT is set and makes sense."""
    root = os.environ.get('PW_ROOT', None)

    if root is None:
        ctx.fatal('PW_ROOT not set')

    git_root = call_stdout(['git', 'rev-parse', '--show-toplevel'],
                           cwd=root).strip()
    if root != git_root:
        ctx.error('PW_ROOT (%s) != `git rev-parse --show-toplevel` (%s)', root,
                  git_root)


@register_into(CHECKS)
def python_version(ctx: DoctorContext):
    """Check the Python version is correct."""
    actual = sys.version_info
    expected = (3, 8)
    if actual[0:2] < expected or actual[0] != expected[0]:
        ctx.error('Python %d.%d.x required, got Python %d.%d.%d', *expected,
                  *actual[0:3])
    elif actual[0:2] > expected:
        ctx.warning('Python %d.%d.x required, got Python %d.%d.%d', *expected,
                    *actual[0:3])


@register_into(CHECKS)
def cipd(ctx: DoctorContext):
    """Check cipd is set up correctly and in use."""
    cipd_path = 'pigweed'

    cipd_exe = shutil.which('cipd')
    if not cipd_exe:
        ctx.fatal('cipd not in PATH')

    temp = tempfile.NamedTemporaryFile(prefix='cipd', delete=False)
    subprocess.run(['cipd', 'acl-check', '-json-output', temp.name, cipd_path],
                   stdout=subprocess.PIPE)
    if not json.load(temp)['result']:
        ctx.fatal(
            "can't access %s CIPD directory, have you run "
            "'cipd auth-login'?", cipd_path)

    commands_expected_from_cipd = [
        'arm-none-eabi-gcc',
        'bazel',
        'bloaty',
        'clang++',
        'gn',
        'ninja',
        'protoc',
    ]

    for command in commands_expected_from_cipd:
        path = shutil.which(command)
        if 'cipd' not in path:
            ctx.warning('not using %s from cipd, got %s', command, path)


def main(strict=False, checks=None):
    """Run all the Check subclasses defined in this file."""

    ctx = DoctorContext(strict=strict)

    if checks is None:
        checks = tuple(CHECKS)

    ctx.debug('Doctor running %d checks...', len(checks))
    for check in checks:
        try:
            ctx.debug('Running %s...', check.__name__)
            ctx.curr_checker = check.__name__
            check(ctx)

        except _Fatal:
            pass

        finally:
            ctx.curr_checker = None

    if ctx.failures:
        ctx.info('Failed checks: %s', ', '.join(ctx.failures))
    else:
        ctx.info('Pigweed environment passes all checks!')
    return len(ctx.failures)


def argument_parser(
        parser: argparse.ArgumentParser = None) -> argparse.ArgumentParser:
    """Create argument parser."""

    if parser is None:
        parser = argparse.ArgumentParser(description=__doc__)

    parser.add_argument(
        '--strict',
        action='store_true',
        help='Run additional checks.',
    )

    return parser


if __name__ == '__main__':
    # By default, display log messages like a simple print statement.
    logging.basicConfig(format='%(message)s', level=logging.INFO)
    sys.exit(main(**vars(argument_parser().parse_args())))
