#!/usr/bin/env python3
# Copyright (c) 2021 Project CHIP 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
#
#   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.

import logging
import os
import re
import subprocess
import sys

import click
import coloredlogs

# Supported log levels, mapping string values required for argument
# parsing into logging constants
__LOG_LEVELS__ = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warn': logging.WARN,
    'fatal': logging.FATAL,
}


@click.command()
@click.option(
    '--log-level',
    default='INFO',
    type=click.Choice(__LOG_LEVELS__.keys(), case_sensitive=False),
    help='Determines the verbosity of script output.')
@click.option(
    '--no-log-timestamps',
    default=False,
    is_flag=True,
    help='Skip timestaps in log output')
@click.option(
    '--image',
    default=[],
    multiple=True,
    help='What images to execute (will be executed one after another)'
)
@click.option(
    '--file-image-list',
    default=None,
    help='Read the images from the given file (contains images one per line)'
)
@click.option(
    '--qemu',
    default=os.environ.get('QEMU_ESP32', 'qemu-system-xtensa'),
    help='QEMU binary to run (generally path to qemu-system-xtensa)'
)
@click.option(
    '--verbose',
    default=False,
    is_flag=True,
    help='More verbose output')
def main(log_level, no_log_timestamps, image, file_image_list, qemu, verbose):
    # Ensures somewhat pretty logging of what is going on
    log_fmt = '%(asctime)s %(levelname)-7s %(message)s'
    if no_log_timestamps:
        log_fmt = '%(levelname)-7s %(message)s'
    coloredlogs.install(level=__LOG_LEVELS__[log_level], fmt=log_fmt)

    image = list(image)

    if file_image_list:
        logging.info("Reading image list from %s", file_image_list)

        basedir = os.path.dirname(file_image_list)

        with open(file_image_list, 'rt') as f:
            for name in f.readlines():
                name = name.strip()

                image_path = name
                if not os.path.isabs(name):
                    image_path = os.path.join(basedir, name)

                logging.info("    Found %s => %s", name, image_path)
                image.append(image_path)

    # the list "image" contains all the images that need to run
    for path in image:
        logging.info("Executing image %s", path)

        status = subprocess.run([qemu, "-nographic", "-no-reboot", "-machine", "esp32",
                                 "-drive", "file=%s,if=mtd,format=raw" % path], capture_output=True)

        # Encoding is NOT valid, but want to not try to decode potential
        # invalid UTF-8 sequences. The strings we care about are ascii anyway
        output = status.stdout.decode('ascii')

        try:
            if status.returncode != 0:
                raise Exception("Execution of %s failed with code %d" %
                                (path, status.returncode))

            # Parse output of the unit test. Generally expect things like:
            # I (3034) CHIP-tests: Starting CHIP tests!
            # ...
            # Various test lines, none ending with "] : FAILED"
            # ...
            # Failed Tests:   0 / 5
            # Failed Asserts: 0 / 77
            # I (3034) CHIP-tests: CHIP test status: 0
            in_test = False
            for line in output.split('\n'):
                if line.endswith('CHIP-tests: Starting CHIP tests!'):
                    in_test = True

                if line.startswith('Failed Tests:') and not line.startswith('Failed Tests:   0 /'):
                    raise Exception("Tests seem failed: %s" % line)

                if line.startswith('Failed Asserts:') and not line.startswith('Failed Asserts: 0 /'):
                    raise Exception("Asserts seem failed: %s" % line)

                if 'CHIP-tests: CHIP test status: 0' in line:
                    in_test = False
                elif 'CHIP-tests: CHIP test status: ' in line:
                    raise Exception("CHIP test status is NOT 0: %s" % line)

                # Ignore FAILED messages not in the middle of a test, to reduce
                # the chance of false posisitves from other logging.
                if in_test and re.match('.*] : FAILED$', line):
                    raise Exception("Step failed: %s" % line)

                # TODO: Figure out why exit(0) in man_app.cpp's tester_task is aborting and fix that.
                if in_test and line.startswith('abort() was called at PC'):
                    raise Exception("Unexpected crash: %s" % line)

            if in_test:
                raise Exception('Not expected to be in the middle of a test when the log ends')

            if verbose:
                print("========== TEST OUTPUT BEGIN ============")
                print(output)
                print("========== TEST OUTPUT END   ============")

            logging.info("Image %s PASSED", path)
        except:
            # make sure output is visible in stdout
            print("========== TEST OUTPUT BEGIN ============")
            print(output)
            print("========== TEST OUTPUT END   ============")
            raise


if __name__ == '__main__':
    main()
