# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""
Generate Rust constants from validated register JSON tree
"""

import io
import logging as log
import sys
import textwrap
import warnings
from datetime import datetime
from typing import Any, Dict, List, Optional, Set, TextIO

from .ip_block import IpBlock
from .multi_register import MultiRegister
from .params import LocalParam
from .register import Register
from .window import Window

REG_VISIBILITY = 'pub(crate)'
FIELD_VISIBILITY = 'pub(crate)'


def genout(outfile: TextIO, msg: str, *args: Any, **kwargs: Any) -> None:
    outfile.write(msg.format(*args, **kwargs))


def indent(s: str, amount: int = 4) -> str:
    """Indents a multi-line string considering the depth of bracketing.

    This function assumes the input string is un-indented.  It will not
    unindent an inapprorpiately indented string.
    """
    result = []
    indent = 0
    for line in s.splitlines():
        indented = []
        comment = False
        for i, ch in enumerate(line):
            if i > 0 and ch == '/' and line[i - 1] == '/':
                comment = True
            if not comment and ch in ")]}":
                indent -= 1
            if i == 0:
                indented.append(' ' * indent * amount)
            if not comment and ch in "([{":
                indent += 1
            indented.append(ch)
        result.append(''.join(indented))
        if line == '':
            result.append('')
    return '\n'.join(result)


def to_snake_case(s: str) -> str:
    """Converts a string from a MixedCaseString to a snake_case_string."""
    val = []
    for i, ch in enumerate(s):
        if i > 0 and ch.isupper():
            val.append('_')
        val.append(ch)
    return ''.join(val)


def to_studly_caps(s: str) -> str:
    """Converts a string from a snake_case_string to a StudlyCapsString."""
    words = [w.capitalize() for w in s.split('_')]
    return ''.join(words)


def to_upper_snake_case(s: str) -> str:
    """Converts a string from a MixedCaseString to a UPPER_SNAKE_CASE_STRING."""
    s = s.upper()
    r = ''
    for i in range(0, len(s)):
        r += s[i] if s[i].isalnum() else '_'
    return r


def first_line(s: str) -> str:
    """Returns the first line of a multi-line string"""
    return s.splitlines()[0]


def format_comment(s: str) -> str:
    """Formats a string to comment wrapped to a 100 character line width

    Returns wrapped string including newline and // comment characters.
    """
    comment = textwrap.wrap(s,
                            width=97,
                            initial_indent='// ',
                            subsequent_indent='// ')
    return '\n'.join(comment) + '\n'


def data_type(name: str, val: int, as_hex: bool) -> str:
    """ Returns proper data type for name-value pair. """

    if name.endswith("_OFFSET") or name.endswith("_BASE_ADDR"):
        return "usize"

    if val.bit_length() > 32:
        log.error(name + " value exceeds 32 bit " + str(val))
        sys.exit(1)

    if not as_hex and val < 0:
        return "i32"

    return "u32"


def gen_const(outstr: TextIO,
              name: str,
              suffix: str,
              val: int,
              existing_defines: Set[str],
              as_hex: bool = False) -> str:
    r"""Produces a pub const string. Result includes newline.

    Arguments:
    name - Name of the constant
    val - Value of the constant
    existing_defines - set of already generated define names.
        Error if `name` is in `existing_defines`.

    Example result:
    name = 'A_NAME'
    val = '10'

    pub const A_NAME: u32 = 10

    """

    suffix = '' if not suffix.strip() else '_' + suffix
    name = name + suffix
    if name in existing_defines:
        log.error("Duplicate pub const for " + name)
        sys.exit(1)

    define_declare = 'pub const ' + name + ': ' + data_type(name, val, as_hex)

    val_str = hex(val) if as_hex else str(val)
    oneline_define = define_declare + ' = ' + val_str + ';'

    existing_defines.add(name)

    output = oneline_define + '\n'
    genout(outstr, output)
    return output


def access(reg: Any) -> str:
    swaccess = getattr(reg, 'swaccess', None)
    if swaccess is None:
        swaccess = 'unspecified'
    else:
        swaccess = swaccess.key
    if swaccess == 'ro':
        return 'ReadOnly'
    elif swaccess == 'wo':
        return 'WriteOnly'
    elif swaccess in ('rw', 'rw0c', 'rw1c', 'unspecified'):
        return 'ReadWrite'
    else:
        warnings.warn('{}: Unknown swaccess type {}'.format(
            reg.name, swaccess))
        return 'ReadWrite'


def gen_field_definitions(
        fieldout: TextIO,
        reg: Any,  # Should be Register|IpBlock
        name: str,
        width: int) -> None:
    genout(fieldout, "{} {} [", FIELD_VISIBILITY, name.upper())
    fields: Any
    if isinstance(reg, Register):
        fields = reg.fields
    elif isinstance(reg, IpBlock):
        fields = reg.interrupts
    else:
        raise TypeError(type(reg))

    for field in fields:
        if field.bits.width() == width:
            genout(fieldout, "],\n")
            break
        genout(fieldout, "\n{} OFFSET({}) NUMBITS({}) [", field.name.upper(),
               field.bits.lsb, field.bits.width())
        if getattr(field, 'enum', None) is not None:
            for enum in field.enum:
                genout(fieldout, "\n{} = {},", enum.name.upper(), enum.value)
            genout(fieldout, "\n],")
        else:
            genout(fieldout, "],")
    else:
        genout(fieldout, "\n],\n")


def gen_const_register(regout: TextIO, fieldout: TextIO, reg: Register,
                       block: IpBlock, rnames: Set[str],
                       existing_defines: Set[str], access_type: Set[str],
                       highest_address: Set[int]) -> None:
    if not block.no_auto_intr and reg.name.startswith('INTR_'):
        rname = "INTR"
    else:
        rname = reg.name.upper()
        gen_field_definitions(fieldout, reg, rname, block.regwidth)

    a = access(reg)
    access_type.add(a)
    highest_address.add(reg.offset + block.regwidth // 8)
    genout(regout, format_comment(first_line(reg.desc)))
    genout(regout, "(0x{:04x} => {} {}: {}<u32, {}::Register>),\n", reg.offset,
           REG_VISIBILITY, reg.name.lower(), a, rname)


def gen_const_window(regout: TextIO, win: Window, block: IpBlock,
                     rnames: Set[str], existing_defines: Set[str],
                     access_type: Set[str], highest_address: Set[int]) -> None:
    genout(regout, format_comment('Memory area: ' + first_line(win.desc)))
    a = access(win)
    access_type.add(a)
    highest_address.add(win.offset + win.items * block.regwidth // 8)
    genout(regout, "(0x{:04x} => {} {}: [{}<u32>; {}]),\n", win.offset,
           REG_VISIBILITY, win.name.lower(), a, win.items)


def gen_rust_module_param(outstr: TextIO, param: LocalParam, module_name: str,
                          existing_defines: Set[str]) -> None:
    # Presently there is only one type (int), however if the new types are
    # added, they potentially need to be handled differently.
    known_types = ["int"]
    if param.param_type not in known_types:
        warnings.warn("Cannot generate a module define of type {}".format(
            param.param_type))
        return

    if param.desc is not None:
        genout(outstr, format_comment(first_line(param.desc)))
    # Heuristic: if the name already has underscores, it's already snake_case,
    # otherwise, assume StudlyCaps and convert it to snake_case.
    param_name = param.name if '_' in param.name else to_snake_case(param.name)
    define_name = to_upper_snake_case(module_name + '_PARAM_' + param_name)
    if param.param_type == "int":
        gen_const(outstr, define_name, '', int(param.value), existing_defines)


def gen_const_module_params(outstr: TextIO, module_data: IpBlock,
                            module_name: str, register_width: int,
                            existing_defines: Set[str]) -> None:
    for param in module_data.params.get_localparams():
        gen_rust_module_param(outstr, param, module_name, existing_defines)

    genout(outstr, format_comment(first_line("Register width")))
    define_name = to_upper_snake_case(module_name + '_PARAM_REG_WIDTH')
    gen_const(outstr, define_name, '', register_width, existing_defines)
    genout(outstr, '\n')


def gen_const_multireg(regout: TextIO, fieldout: TextIO,
                       multireg: MultiRegister, block: IpBlock,
                       rnames: Set[str], existing_defines: Set[str],
                       access_type: Set[str],
                       highest_address: Set[int]) -> None:
    reg = multireg.regs[0]
    rname = reg.name[:-2].upper()
    rlen = len(multireg.regs)
    genout(regout, format_comment(first_line(reg.desc)))
    a = access(reg)
    access_type.add(a)
    highest_address.add(reg.offset + rlen * block.regwidth // 8)
    genout(regout, "(0x{:04x} => {} {}: [{}<u32, {}::Register>; {}]),\n",
           reg.offset, REG_VISIBILITY, rname.lower(), a, rname, rlen)
    gen_field_definitions(fieldout, reg, rname, block.regwidth)


def gen_const_interrupts(fieldout: TextIO, block: IpBlock, component: str,
                         regwidth: int, existing_defines: Set[str]) -> None:
    # If no_auto_intr is true, then we do not generate common defines,
    # because the bit offsets for a particular interrupt may differ between
    # the interrupt enable/state/test registers.
    if block.no_auto_intr:
        return
    genout(fieldout, format_comment(first_line("Common Interrupt Offsets")))
    gen_field_definitions(fieldout, block, "INTR", block.regwidth)


def gen_tock(block: IpBlock, outfile: TextIO, src_lic: Optional[str],
             src_copy: str, version_stamp: Dict[str, str]) -> int:
    rnames = block.get_rnames()

    paramout = io.StringIO()
    regout = io.StringIO()
    genout(regout, 'register_structs! {{\npub {}Registers {{\n',
           to_studly_caps(block.name))
    fieldout = io.StringIO()
    genout(fieldout, 'register_bitfields![u32,\n')

    # This tracks the defines that have been generated so far, so we
    # can error if we attempt to duplicate a definition
    existing_defines = set()  # type: Set[str]
    access_type = set()  # type: Set[str]
    highest_address = set()  # type: Set[int]

    gen_const_module_params(paramout, block, block.name, block.regwidth,
                            existing_defines)

    gen_const_interrupts(fieldout, block, block.name, block.regwidth,
                         existing_defines)

    for rb in block.reg_blocks.values():
        for x in rb.entries:
            if isinstance(x, Register):
                gen_const_register(regout, fieldout, x, block, rnames,
                                   existing_defines, access_type,
                                   highest_address)
                continue

            if isinstance(x, MultiRegister):
                gen_const_multireg(regout, fieldout, x, block, rnames,
                                   existing_defines, access_type,
                                   highest_address)
                continue

            if isinstance(x, Window):
                gen_const_window(regout, x, block, rnames, existing_defines,
                                 access_type, highest_address)
                continue

    paramstr = paramout.getvalue()
    paramout.close()

    end = sorted(highest_address)[-1]
    # End the register file.
    genout(regout, '(0x{:04x} => @END),\n', end)
    # Close the "pub <block>" declaration, then the "register_structs!" macro.
    genout(regout, '}}\n}}\n\n')
    regstr = regout.getvalue()
    regout.close()

    # Close the "register_bitfields!" macro.
    genout(fieldout, '];\n\n')
    fieldstr = fieldout.getvalue()
    fieldout.close()

    genout(outfile, '// Generated register constants for {}\n\n', block.name)
    genout(outfile, '// Built for {}\n',
           version_stamp.get('BUILD_GIT_VERSION', '<unknown>'))
    genout(outfile, '// https://github.com/lowRISC/opentitan/tree/{}\n',
           version_stamp.get('BUILD_SCM_REVISION', '<unknown>'))
    genout(outfile, '// Tree status: {}\n',
           version_stamp.get('BUILD_SCM_STATUS', '<unknown>'))
    tm = int(version_stamp.get('BUILD_TIMESTAMP', 0))
    dt = datetime.utcfromtimestamp(tm) if tm else datetime.utcnow()
    genout(outfile, '// Build date: {}\n\n', dt.isoformat())

    if src_copy:
        genout(outfile, '// Copyright information found in source file:\n')
        genout(outfile, '// {}\n\n', src_copy)
    if src_lic is not None:
        genout(outfile, '// Licensing information found in source file:\n')
        for line in src_lic.splitlines():
            genout(outfile, '// {}\n', line)
        genout(outfile, '\n')
    genout(outfile, "use kernel::utilities::registers::{{\n")
    genout(outfile, "    register_bitfields, register_structs, {}\n",
           ', '.join(sorted(access_type)))
    genout(outfile, "}};\n")

    outfile.write(indent(paramstr))
    outfile.write(indent(regstr))
    outfile.write(indent(fieldstr))

    genout(outfile, '// End generated register constants for {}\n', block.name)
    return 0


def test_gen_const() -> None:
    outstr = io.StringIO()

    basic_oneline = 'pub const MACRO_NAME 10;\n'
    assert (gen_const(outstr, 'MACRO', 'NAME', 10, set()) == basic_oneline)

    long_macro_name = 'A_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_LONG_MACRO_NAME'
    multiline = ('pub const ' + long_macro_name + ' \\\n' + '  1000000000;\n')

    assert (gen_const(outstr, long_macro_name, '', 1000000000,
                      set()) == multiline)
