#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020  The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC

from prjxray import util
import os
import json
'''
Local utils script to hold shared code of the 005-tilegrid fuzzer scripts
'''


class TileFrames:
    """
    Class for getting the number of frames used for configuring a tile
    with the specified baseaddress using the information from the part's json file
    """

    def __init__(self):
        self.tile_address_to_frames = dict()

    def get_baseaddress(self, region, bus, row, column):
        assert bus == 'BLOCK_RAM' or bus == 'CLB_IO_CLK', 'Incorrect block type'
        address = (row << 17) + (column << 7) + (
            (1 << 22) if region == 'bottom' else 0) + (
                (1 << 23) if bus == 'BLOCK_RAM' else 0)
        return address

    def initialize_address_to_frames(self):
        with open(os.path.join(os.getenv('XRAY_FAMILY_DIR'),
                               os.getenv('XRAY_PART'), 'part.json')) as pf:
            part_json = json.load(pf)
        for clock_region, rows in part_json['global_clock_regions'].items():
            for row, buses in rows['rows'].items():
                for bus, columns in buses['configuration_buses'].items():
                    for column, frames in columns[
                            'configuration_columns'].items():
                        address = self.get_baseaddress(
                            clock_region, bus, int(row), int(column))
                        assert address not in self.tile_address_to_frames
                        self.tile_address_to_frames[address] = frames[
                            'frame_count']

    def get_tile_frames(self, baseaddress):
        if len(self.tile_address_to_frames) == 0:
            self.initialize_address_to_frames()
        assert baseaddress in self.tile_address_to_frames, "Base address not found in the part's json file"
        return self.tile_address_to_frames[baseaddress]


def get_entry(tile_type, block_type):
    """ Get frames and words for a given tile_type (e.g. CLBLL) and block_type (CLB_IO_CLK, BLOCK_RAM, etc). """
    return {
        # (tile_type, block_type): (frames, words, height)
        ("CLBLL", "CLB_IO_CLK"): (36, 2, None),
        ("CLBLM", "CLB_IO_CLK"): (36, 2, None),
        ("HCLK", "CLB_IO_CLK"): (26, 1, None),
        ("INT", "CLB_IO_CLK"): (28, 2, None),
        ("BRAM", "CLB_IO_CLK"): (28, 10, None),
        ("BRAM", "BLOCK_RAM"): (128, 10, None),
        ("DSP", "CLB_IO_CLK"): (28, 2, None),
    }.get((tile_type, block_type), None)


def get_int_params():
    int_frames, int_words, _ = get_entry('INT', 'CLB_IO_CLK')
    return int_frames, int_words


def add_tile_bits(
        tile_name,
        tile_db,
        baseaddr,
        offset,
        frames,
        words,
        tile_frames,
        verbose=False):
    '''
    Record data structure geometry for the given tile baseaddr
    For most tiles there is only one baseaddr, but some like BRAM have multiple
    Notes on multiple block types:
    https://github.com/SymbiFlow/prjxray/issues/145
    '''
    bits = tile_db['bits']
    block_type = util.addr2btype(baseaddr)

    # Extract the information about the maximal number of frames from the part's json
    max_frames = tile_frames.get_tile_frames(baseaddr)
    if frames > max_frames:
        print(
            "Warning: The number of frames for base address {} specified for the tile {} ({}) exceeds the maximum allowed value ({}). Falling back to the maximum value."
            .format(hex(baseaddr), tile_name, frames, max_frames))
        frames = max_frames
    # If frames count is None then use the maximum
    if frames is None:
        frames = max_frames

    assert offset <= 100, (tile_name, offset)
    # Few rare cases at X=0 for double width tiles split in half => small negative offset
    assert offset >= 0 or "IOB" in tile_name, (
        tile_name, hex(baseaddr), offset)
    assert 1 <= words <= 101, words
    assert offset + words <= 101, (
        tile_name, offset + words, offset, words, block_type)

    baseaddr_str = '0x%08X' % baseaddr
    block = bits.get(block_type, None)
    if block is not None:
        verbose and print(
            "%s: existing defintion for %s" % (tile_name, block_type))
        assert block["baseaddr"] == baseaddr_str
        assert block["frames"] == frames, (block, frames)
        assert block["offset"] == offset, "%s; orig offset %s, new %s" % (
            tile_name, block["offset"], offset)
        assert block["words"] == words
        return
    block = bits.setdefault(block_type, {})

    # FDRI address
    block["baseaddr"] = baseaddr_str
    # Number of frames this entry is sretched across
    # that is the following FDRI addresses are used: range(baseaddr, baseaddr + frames)
    block["frames"] = frames

    # Index of first word used within each frame
    block["offset"] = offset

    # Number of words used by tile.
    block["words"] = words
