# Copyright (c) 2020 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright 2019 Google, Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from itertools import cycle
import logging
import shlex

Import('*')

from grammar import Grammar

from gem5_scons import Transform, warning, error

import os.path

if env['CONF']['USE_ARM_FASTMODEL']:
    if env['CONF']['USE_SYSTEMC']:
        env.TagImplies('arm fastmodel', 'arm isa')
    else:
        warning('ARM Fast Models require systemc support')
        env['CONF']['USE_ARM_FASTMODEL'] = False


systemc_home = Dir('#/src/systemc/ext/systemc_home')
env['ENV']['SYSTEMC_HOME'] = systemc_home.abspath

def extract_var(name):
    val = env['CONF'].get(name, None)
    if val is None:
        error(f'{name} is not set')
    if env['CONF']['USE_ARM_FASTMODEL']:
        print(f'{name} = {val}')
    # Make sure the value of this variable shows up as an environment variable
    # for commands scons runs.
    env['ENV'][name] = val
    return val

pvlib_home, maxcore_home, armlmd_license_file = \
    list(map(extract_var, ('PVLIB_HOME', 'MAXCORE_HOME',
                           'ARMLMD_LICENSE_FILE')))

pvlib_home = Dir(pvlib_home)
maxcore_home = Dir(maxcore_home)

pvlib_flavor = env['CONF']['PVLIB_FLAVOR']
pvlib_lib_dir = pvlib_home.Dir('lib').Dir(pvlib_flavor)

simulation_engine_name = 'libMAXCOREInitSimulationEngine.3.so'
simulation_engine_lib = env.Command(
            Dir(env['BUILDDIR']).File(simulation_engine_name),
            pvlib_lib_dir.File(simulation_engine_name),
            MakeAction("cp ${SOURCE} ${TARGET}", Transform('COPY')))

arm_singleton_registry_name = 'arm_singleton_registry.so'
arm_singleton_registry_lib = env.Command(
            Dir(env['BUILDDIR']).File(arm_singleton_registry_name),
            pvlib_lib_dir.File(arm_singleton_registry_name),
            MakeAction("cp ${SOURCE} ${TARGET}", Transform('COPY')))


def staticify(env, name):
    ''' Check for a static version of the library named 'name', and if it
        exists return a File node for it explicitly. Otherwise pass 'name'
        through for normal processing.'''

    static_name = env.subst('${LIBPREFIX}' + name + '${LIBSUFFIX}')

    for path in env.Flatten(env['LIBPATH']):
        full_name = Dir(path).File(static_name).get_abspath()
        if os.path.isfile(full_name):
            return File(full_name)
    if env['CONF']['USE_ARM_FASTMODEL']:
        warning("Failed to find FM static lib: " + name)
    return name

# Adjust the build environment to support building in Fast Models.

env.Append(CCFLAGS='-pthread')

cpppaths = (
    pvlib_home.Dir('examples/SystemCExport/Common/include'),
    pvlib_home.Dir('include'),
    pvlib_home.Dir('include/fmruntime'),
    pvlib_home.Dir('include/fmruntime/eslapi'),
    pvlib_home.Dir('Iris/include'),

    systemc_home.Dir('include'),

    maxcore_home.Dir('AMBA-PV/include'),
)
env.Append(CPPPATH=cpppaths)

lib_paths = (
    pvlib_lib_dir,
    pvlib_home.Dir('Iris').Dir(pvlib_flavor),
)
env.Append(LIBPATH=lib_paths)

# Per ARM's 11.16 release note, a platform build with simgen automatically
# copies libraries into the build target directory along with the other
# dependencies. Therefore, we only need to add each simgen result into rpath and
# no other shared librarires are required here.
fm_static_libs = (
    'components',
    'pvbus',
    'armctmodel',
    'fmruntime',
    'IrisSupport',
)
for lib in fm_static_libs:
    SourceLib(staticify(env, lib), tags='arm fastmodel')

SourceLib('atomic', tags='arm fastmodel')
SourceLib('dl', tags='arm fastmodel')
SourceLib('rt', tags='arm fastmodel')

class ProjectFileParser(Grammar):
    def __init__(self):
        self.log = logging.getLogger('fm_proj_ply')
        if GetOption('verbose'):
            self.log.setLevel(logging.DEBUG)

        self.yacc_kwargs['write_tables'] = False

        self.yacc_kwargs['debuglog'] = self.log
        self.yacc_kwargs['errorlog'] = self.log

        self.lex_kwargs['debuglog'] = self.log
        self.lex_kwargs['errorlog'] = self.log

    class Param(object):
        def __init__(self, is_object):
            self.is_object = is_object

        def __str__(self):
            return self._to_str(0)

    class StringParam(Param):
        def __init__(self, name, value):
            super().__init__(is_object=False)
            self.name = name
            self.value = value

        def _to_str(self, indent):
            indent_str = "    " * indent
            return indent_str + self.name + ' = \"' + self.value + '\"'

    class ObjectParam(Param):
        def __init__(self, type_name, name, params):
            super().__init__(is_object=True)
            self.type_name = type_name
            self.name = name
            self.params = params

        def _to_str(self, indent):
            indent_str = "    " * indent
            val = indent_str + self.type_name
            if self.name is not None:
                val += ' "' + self.name + '"'
            val += "\n" + indent_str + "{\n"
            for param in self.params:
                val += param._to_str(indent + 1) + "\n"
            val += indent_str + "}"
            return val

    #########
    # Lexer #
    #########

    tokens = (
        # identifier
        'ID',

        # string literal
        'STRLIT',

        # = { } ;
        'EQUALS',
        'LBRACE',
        'RBRACE',
        'SEMI',
    )

    t_ID = r'[A-Za-z_]\w*'

    def t_STRLIT(self, t):
        r'"([^"])*"'
        # strip off quotes
        t.value = t.value[1:-1]
        return t

    t_EQUALS = r'='
    t_LBRACE = r'\{'
    t_RBRACE = r'\}'
    t_SEMI = r';'

    def t_NEWLINE(self, t):
        r'\n+'
        t.lexer.lineno += t.value.count('\n')

    t_ignore = ' \t\x0c'

    ##########
    # Parser #
    ##########

    def p_object(self, t):
        'object : object_heading LBRACE params RBRACE'
        t[0] = self.ObjectParam(t[1][0], t[1][1], t[3])

    def p_object_heading_0(self, t):
        'object_heading : ID STRLIT'
        t[0] = (t[1], t[2])

    def p_object_heading_1(self, t):
        'object_heading : ID'
        t[0] = (t[1], None)

    def p_params_0(self, t):
        'params : '
        t[0] = []

    def p_params_1(self, t):
        'params : param params'
        t[0] = [t[1]] + t[2]

    def p_param_0(self, t):
        'param : ID EQUALS STRLIT SEMI'
        t[0] = self.StringParam(t[1], t[3])

    def p_param_1(self, t):
        'param : object'
        t[0] = t[1]


# If fast model is disabled, ARMLMD_LICENSE_COUNT will be 0 which will break
# the cycle() iterator below. The fast model components won't be built, but
# they still need to be set up successfully with valid license slots.
license_count = max(int(env['CONF']['ARMLMD_LICENSE_COUNT']), 1)
arm_licenses = list((Value(object()) for i in range(license_count)))
license_cycle = cycle(arm_licenses)

# HACK: Make sure the gic protocol headers are somewhere we can find them.
# These should start out alongside other headers fast model provides which we
# are already able to include, but unfortunately they're in the examples
# directory.
gicv3_comms_headers = (
        'gicv3_comms_base.h', 'gicv3_comms_if.h', 'gicv3_comms_sockets.h')
examples_common_dir = pvlib_home.Dir('examples/SystemCExport/Common')
gic_protocol_path = 'Protocols/GICv3Comms'
gic_protocol_dest = Dir(env['BUILDDIR']).Dir(gic_protocol_path)
gic_protocol_src = examples_common_dir.Dir(gic_protocol_path)

for header in gicv3_comms_headers:
    Command(gic_protocol_dest.File(header), gic_protocol_src.File(header),
            Copy('${TARGET}', '${SOURCE}'))
# Since we are copying the source files to a different directory, Scons's
# dependency scanner does not pick up the dependency between these files.
# Specify them manually.
env.Depends(gic_protocol_dest.File('gicv3_comms_base.h'),
            gic_protocol_dest.File('gicv3_comms_if.h'))
env.Depends(gic_protocol_dest.File('gicv3_comms_sockets.h'),
            gic_protocol_dest.File('gicv3_comms_if.h'))

common_headers = ('lisa_protocol_types.h', 'tlm_has_get_protocol_types.h')
for header in common_headers:
    header_target = gic_protocol_dest.Dir('include').File(header)
    header_src = examples_common_dir.Dir('include').File(header)
    Command(header_target, header_src, Copy('${TARGET}', '${SOURCE}'))

class ArmFastModelComponent(object):
    def __init__(self, project_file, *extra_deps, tags=None):
        if not tags:
            tags = ['arm fastmodel']
        self.tags = tags
        project_file = File(project_file)
        project_file_dir = project_file.Dir('.')

        parser = ProjectFileParser()
        proj = parser.parse_file(project_file.srcnode().abspath)

        # Top level component.
        tlc = None
        # Config name.
        config_name = None
        # simgen_arg
        simgen_command_line = ''

        # Scan for particular properties of the project.
        for param in proj.params:
            if not param.is_object:
                if param.name == 'TOP_LEVEL_COMPONENT':
                    tlc = param.value
                elif param.name == 'ACTIVE_CONFIG_LINUX':
                    config_name = param.value

        for param in proj.params:
            if param.name == config_name:
                for sub_param in param.params:
                    if sub_param.name == 'SIMGEN_COMMAND_LINE':
                        simgen_command_line = sub_param.value

        assert tlc is not None and config_name is not None

        simgen_dir = project_file_dir.Dir(config_name)

        def simgen_static(name):
            return simgen_dir.File(env.subst(
                        '${LIBPREFIX}%s${LIBSUFFIX}' % name))

        def simgen_shared(name):
            return simgen_dir.File(env.subst(
                        '${SHLIBPREFIX}%s${SHLIBSUFFIX}' % name))

        static_libs = [
            'scx-%s-%s' % (tlc, config_name),
            'scx',
        ]
        shared_libs = [
            '%s-%s' % (tlc, config_name),
        ]

        static_lib_nodes = list(map(simgen_static, static_libs))
        shared_lib_nodes = list(map(simgen_shared, shared_libs))
        # We need to use the static libraries as files so that the linker
        # doesn't use the shared versions of them instead. We need to use
        # the shared libraries by name so that the linker will apply RPATH
        # and be able to find them at run time. If a shared libary includes
        # a path, the dynamic linker will apparently ignore RPATH when looking
        # for it.
        lib_nodes = static_lib_nodes + shared_lib_nodes

        gen_dir = simgen_dir.Dir('gen')

        header = gen_dir.File('scx_evs_%s.h' % tlc)

        self.headers = [header]
        self.headerpaths = [gen_dir]
        self.libs = static_lib_nodes + shared_libs
        self.libpaths = [simgen_dir]
        # Simgen also puts required share library under the project folder.
        self.rpaths = [simgen_dir, project_file_dir]
        self.log = gen_dir.File('build_%s.log' % tlc)
        self.simgen_cmd = env.subst('${CONF["SIMGEN"]} -p %s '
            '--configuration %s -b --verbose off --num-build-cpus %d -I %s %s '
            '--build-dir %s >%s') % \
            (shlex.quote(project_file.srcnode().abspath),
             shlex.quote(config_name),
             GetOption('num_jobs'),
             shlex.quote(Dir('#/src').srcnode().abspath),
             simgen_command_line,
             shlex.quote(simgen_dir.abspath),
             shlex.quote(self.log.abspath))

        sources = [project_file]
        sources.extend(extra_deps)
        # The simgen-generated .lisa files may #include these gicv3 files, but
        # SCons does not detect this dependency since they are generated files.
        # Add the dependencies manually.
        sources.extend([gic_protocol_dest.File('gicv3_comms_sockets.h'),
                        gic_protocol_dest.File('gicv3_comms_base.h')])
        env.Command(lib_nodes + self.headers + [self.log], sources,
                    Action(self.simgen_builder, Transform('SIMGEN')))
        # Distribute simgen actions among ARM license slots. All actions which
        # have a given license as a "side effect" will be serialized relative
        # to each other, meaning the number of licenses being used concurrently
        # will never be larger than the number of license nodes.
        #
        # This allocation is fixed and may not be as optimal as a dynamic one,
        # but the difference is probably not significant.
        env.SideEffect(next(license_cycle), lib_nodes[0])

        # We need a copy of the simulation engine lib and arm_singleton_registry
        # (introduced in 11.16) alongside the executable.
        Depends(lib_nodes[0], simulation_engine_lib)
        Depends(lib_nodes[0], arm_singleton_registry_lib)

    def prepare_env(self, env):
        env.Append(LIBPATH=self.libpaths)
        env.AddLocalRPATH(*self.rpaths)
        env.Append(CPPPATH=self.headerpaths)
        # Put these libraries earlier in the list by setting priority.
        for lib in self.libs:
            SourceLib(lib, priority=1, tags=self.tags)

    def simgen_builder(self, target, source, env):
        cmd = self.simgen_cmd
        if not GetOption('verbose'):
            cmd = "@" + cmd
        res = env.Execute(cmd)
        # Print output when execution return non-zero or in verbose mode.
        if res or GetOption('verbose'):
            env.Execute('@cat %s' % self.log.abspath)
        return res


Export('ArmFastModelComponent')

PySource('m5', 'arm_fast_model.py', tags='arm fastmodel')
Source('fastmodel.cc', tags='arm fastmodel')

SimObject('FastModel.py', sim_objects=[
    'AmbaToTlmBridge64', 'AmbaFromTlmBridge64'], tags='arm fastmodel')
Source('amba_to_tlm_bridge.cc', tags='arm fastmodel')
Source('amba_from_tlm_bridge.cc', tags='arm fastmodel')
Source('remote_gdb.cc', tags='arm fastmodel')
