// Copyright 2025 Google LLC
//
// 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
//
//     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.

package kelvin.soc

import chisel3._

/**
 * A simple case class for defining memory regions.
 *
 * @param base The base address of the memory region.
 * @param size The size of the memory region in bytes.
 */
case class AddressRange(base: BigInt, size: BigInt) {
  /**
   * Checks if a given dynamic address is within this range.
   * @param addr The address to check.
   * @return A Chisel Bool indicating if the address is contained.
   */
  def contains(addr: UInt): Bool = {
    (addr >= base.U) && (addr < (base + size).U)
  }
}

/**
 * Defines the parameters for a host (master) in the crossbar.
 * @param name The unique name of the host.
 * @param width The data width of the host interface.
 */
case class HostConfig(name: String, width: Int, clockDomain: String = "main")

/**
 * Defines the parameters for a device (slave) in the crossbar.
 * @param name The unique name of the device.
 * @param addr A sequence of AddressRanges that this device occupies.
 * @param clockDomain An identifier for the clock domain this device belongs to.
 * @param width The data width of the device interface.
 */
case class DeviceConfig(
  name: String,
  addr: Seq[AddressRange],
  clockDomain: String = "main",
  width: Int = 32
)

/**
 * This object contains the complete, concrete configuration for the Kelvin SoC crossbar,
 * translated from the original tl_config.hjson file.
 */
object CrossbarConfig {
  // List of all host (master) interfaces.
  val hosts = Seq(
    HostConfig("kelvin_core", width = 128),
    HostConfig("ibex_core_i", width = 32, clockDomain = "ibex"),
    HostConfig("ibex_core_d", width = 32, clockDomain = "ibex")
  )

  // List of all device (slave) interfaces with their address maps.
  val devices = Seq(
    DeviceConfig("kelvin_device", Seq(
      AddressRange(0x00000000, 0x2000),    // 8kB
      AddressRange(0x00010000, 0x8000),    // 32kB
      AddressRange(0x00030000, 0x1000)     // 4kB
    ), width = 128),
    DeviceConfig("rom",  Seq(AddressRange(0x10000000, 0x8000))),      // 32kB
    DeviceConfig("sram", Seq(AddressRange(0x20000000, 0x400000))),    // 4MB
    DeviceConfig("uart0", Seq(AddressRange(0x40000000, 0x1000))),
    DeviceConfig("uart1", Seq(AddressRange(0x40010000, 0x1000))),
    DeviceConfig(
      name = "spi0",
      addr = Seq(AddressRange(0x40020000, 0x1000)),
      clockDomain = "spi" // This device is on a separate clock domain
    )
  )

  // A map defining which hosts are allowed to connect to which devices.
  val connections = Map(
    "kelvin_core" -> Seq("sram", "uart1", "spi0", "kelvin_device"),
    "ibex_core_i" -> Seq("rom", "sram"),
    "ibex_core_d" -> Seq("rom", "sram", "uart0", "kelvin_device")
  )
}

/**
 * A standalone validator for the CrossbarConfig.
 *
 * This object can be run to check for configuration errors, such as overlapping
 * address ranges between devices.
 */
object CrossbarConfigValidator extends App {
  val devices = CrossbarConfig.devices

  println("Running CrossbarConfig validation...")

  // Check for address range collisions
  for (i <- devices.indices) {
    for (j <- i + 1 until devices.length) {
      val dev1 = devices(i)
      val dev2 = devices(j)

      for (range1 <- dev1.addr) {
        for (range2 <- dev2.addr) {
          val start1 = range1.base
          val end1 = range1.base + range1.size
          val start2 = range2.base
          val end2 = range2.base + range2.size

          // Check for overlap: max(start1, start2) < min(end1, end2)
          val overlap = (start1 < end2) && (start2 < end1)

          if (overlap) {
            val errorMsg =
              s"""
                 |FATAL: Address range collision detected!
                 |  Device 1: ${dev1.name} -> Range [0x${start1.toString(16)}, 0x${(end1 - 1).toString(16)}]
                 |  Device 2: ${dev2.name} -> Range [0x${start2.toString(16)}, 0x${(end2 - 1).toString(16)}]
               """.stripMargin
            System.err.println(errorMsg)
            throw new Exception("Crossbar configuration validation failed.")
          }
        }
      }
    }
  }

  println("Validation successful: No address range collisions found.")

  // Pretty-print the configuration
  println("\n--- Crossbar Configuration ---")
  println("Hosts:")
  CrossbarConfig.hosts.foreach(h => println(s"  - ${h.name}"))

  println("\nDevices:")
  CrossbarConfig.devices.foreach {
    d =>
      println(s"  - ${d.name} (${d.clockDomain} clock domain)")
      d.addr.foreach {
        a =>
          println(f"    - 0x${a.base}%08x - 0x${a.base + a.size - 1}%08x (Size: ${a.size / 1024}kB)")
      }
  }

  println("\nConnections:")
  CrossbarConfig.connections.foreach {
    case (host, devices) =>
      println(s"  - ${host} -> [${devices.mkString(", ")}]")
  }
  println("\n--------------------------")
}
