#!/usr/bin/env python3

#
# Copyright (c) 2021 Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# 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
#
# 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 argparse
import subprocess
import sys

def __print_arguments(args):
    if isinstance(args, list):
        print("$ " + " ".join(args))
    else:
        print(args)

def Popen(args, **kwargs):
    __print_arguments(args)
    return subprocess.Popen(args, **kwargs)

def call(args, **kwargs):
    __print_arguments(args)
    return subprocess.call(args, **kwargs)

def check_call(args, **kwargs):
    __print_arguments(args)
    return subprocess.check_call(args, **kwargs)

def check_output(args, **kwargs):
    __print_arguments(args)
    return subprocess.check_output(args, **kwargs)

def run_corstone_300(args):
    # Verify supported FVP version
    version = subprocess.check_output(['FVP_Corstone_SSE-300_Ethos-U55', '--version']).decode()
    supported_version = ['11.13', '11.14']

    if not [s for s in supported_version if s in version]:
        raise Exception("Incorrect FVP version. Supported versions are '{}'.".format(supported_version))

    # FVP executable
    cmd = ['FVP_Corstone_SSE-300_Ethos-U55']

    # NPU configuration
    cmd += ['-C', 'ethosu.num_macs=' + str(args.macs)]

    # Output parameters
    cmd += ['-C', 'mps3_board.visualisation.disable-visualisation=1',
            '-C', 'mps3_board.telnetterminal0.start_telnet=0',
            '-C', 'mps3_board.uart0.out_file="-"',
            '-C', 'mps3_board.uart0.unbuffered_output=1',
            '-C', 'mps3_board.uart0.shutdown_on_eot=1']

    cmd += args.args

    # Run FVP and tee output to console while scanning for exit tag
    ret = 1
    proc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while True:
        line = proc.stdout.readline().decode()
        if not line:
                break

        if 'Application exit code: 0.' in line:
            ret = 0

        sys.stdout.write(line)
        sys.stdout.flush()

    return ret

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Run a test with given test command and test binary.')
    parser.add_argument('-t', '--target', choices=['corstone-300'], required=True, help='FVP target.')
    parser.add_argument('-a', '--arch', choices=['ethos-u55'], default='ethos-u55', help='NPU architecture.')
    parser.add_argument('-m', '--macs', type=int, choices=[32, 64, 128, 256], default=128, help='NPU number of MACs.')
    parser.add_argument('args', nargs='+', help='Arguments.')
    args = parser.parse_args()

    if args.target == 'corstone-300':
        sys.exit(run_corstone_300(args))
