#!/usr/bin/env python3
# tools/parsecallstack.py
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.  The
# ASF licenses this file to you 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 argparse
import os


def parse_args():

    parser = argparse.ArgumentParser(
        """
        parsecallstack.py -c CPUTYPE -f FILENAME\n\
        This file can get the call stack when you get the log with the
        register values from R0 to R15, together with the stack dump.\n
        Then you will get a file with name callstack.cmm, run this file
        in Trace32, load the symbol according to the indication, the call
        stack will pop up.\n
        Trace32 software is available at: https://www.lauterbach.com
        """
    )

    parser.add_argument(
        "-f",
        "--filename",
        action="store",
        help="log file with registers and stack information",
    )
    parser.add_argument(
        "-c",
        "--cputype",
        action="store",
        help='''It supports ARM family CPU such as:
            "CortexM0" "CortexM1"  "CortexM3"  "CortexM4"
            "CortexM7" "CortexM23" "CortexM33" "CortexM35P"
            "CortexR5" "CortexR7"  "CortexA5"  "CortexA7"''',
    )

    return parser.parse_args()


def get_regs(filename):

    reglist = []
    with open(filename, mode="r") as fl:
        for line in fl:
            lst = line.strip("\n").split(" ")
            if "R0:" in lst:
                reglist = lst[-8:]
            if "R8:" in lst:
                reglist += lst[-8:]

    return reglist


def get_stackvalue(filename):

    stackvalue = []
    first = 1
    with open(filename, mode="r") as fl:
        for line in fl:
            lst = line.strip("\n").split(" ")
            if "up_stackdump:" in lst:
                if first == 1:
                    first += 1
                    # strip ":" of sp
                    sp = lst[-9].strip(":")
                    # The first item is the sp to restore the stack.
                    stackvalue.append(sp)
                stackvalue += lst[-8:]

    return stackvalue


def generate_cmm(cpu, regs, stackvalue):

    filename = os.path.join(os.getcwd(), "callstack.cmm")
    with open(filename, mode="w") as fl:
        # Select the CPU and symbol.
        fl.write("SYStem.CPU %d\n" % cpu)
        fl.write("SYS.M UP\n")
        fl.write("Data.LOAD *\n")
        fl.write("\n")

        # Set R0-R15.
        for num in range(len(regs)):
            fl.write("Register.Set R%d 0x%s\n" % num, regs[num])
        fl.write("\n")

        # Recover the value in stack.
        sp = int(stackvalue[0], 16)
        for num in range(len(stackvalue) - 1):
            address = hex(sp + num * 4)
            value = stackvalue[num + 1]
            fl.write("Data.Set ZSD:%d %%LE %%Long 0x%d\n" % address, value)
        fl.write("\n")

        # Show the call stack.
        fl.write("data.view %%sYmbol.long %x\n" % sp)
        fl.write("frame.view /Locals /Caller\n")


if __name__ == "__main__":
    args = parse_args()
    regs = get_regs(args.filename)
    stackvalue = get_stackvalue(args.filename)
    generate_cmm(args.cpu, regs, stackvalue)
