// SPDX-License-Identifier: Apache-2.0

package chiselTests

import chisel3._
import chisel3.experimental._
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers

class ScalaIntervalSimulatorSpec extends AnyFreeSpec with Matchers {
  "clip tests" - {
    "Should work for closed ranges" in {
      val sim = ScalaIntervalSimulator(range"[2,4]")
      sim.clip(BigDecimal(1.0)) should be (2.0)
      sim.clip(BigDecimal(2.0)) should be (2.0)
      sim.clip(BigDecimal(3.0)) should be (3.0)
      sim.clip(BigDecimal(4.0)) should be (4.0)
      sim.clip(BigDecimal(5.0)) should be (4.0)
    }
    "Should work for closed ranges with binary point" in {
      val sim = ScalaIntervalSimulator(range"[2,6].2")
      sim.clip(BigDecimal(1.75)) should be (2.0)
      sim.clip(BigDecimal(2.0))  should be (2.0)
      sim.clip(BigDecimal(2.25)) should be (2.25)
      sim.clip(BigDecimal(2.5))  should be (2.5)
      sim.clip(BigDecimal(5.75)) should be (5.75)
      sim.clip(BigDecimal(6.0))  should be (6.0)
      sim.clip(BigDecimal(6.25)) should be (6.0)
      sim.clip(BigDecimal(6.5))  should be (6.0)
      sim.clip(BigDecimal(8.5))  should be (6.0)
    }
    "Should work for open ranges" in {
      val sim = ScalaIntervalSimulator(range"(2,4)")
      sim.clip(BigDecimal(1.0)) should be (3.0)
      sim.clip(BigDecimal(2.0)) should be (3.0)
      sim.clip(BigDecimal(3.0)) should be (3.0)
      sim.clip(BigDecimal(4.0)) should be (3.0)
      sim.clip(BigDecimal(5.0)) should be (3.0)
    }
    "Should work for open ranges with binary point" in {
      val sim = ScalaIntervalSimulator(range"(2,6).2")
      sim.clip(BigDecimal(1.75)) should be (2.25)
      sim.clip(BigDecimal(2.0))  should be (2.25)
      sim.clip(BigDecimal(2.25)) should be (2.25)
      sim.clip(BigDecimal(2.5))  should be (2.5)
      sim.clip(BigDecimal(5.75)) should be (5.75)
      sim.clip(BigDecimal(6.0))  should be (5.75)
      sim.clip(BigDecimal(6.25)) should be (5.75)
      sim.clip(BigDecimal(6.5))  should be (5.75)
      sim.clip(BigDecimal(8.5))  should be (5.75)
    }
  }
  "wrap tests" - {
    "Should work for closed ranges" in {
      val sim = ScalaIntervalSimulator(range"[2,6]")
      sim.wrap(BigDecimal(1.0)) should be (6.0)
      sim.wrap(BigDecimal(2.0)) should be (2.0)
      sim.wrap(BigDecimal(3.0)) should be (3.0)
      sim.wrap(BigDecimal(4.0)) should be (4.0)
      sim.wrap(BigDecimal(5.0)) should be (5.0)
      sim.wrap(BigDecimal(6.0)) should be (6.0)
      sim.wrap(BigDecimal(7.0)) should be (2.0)
    }
    "Should work for closed ranges with binary point" in {
      val sim = ScalaIntervalSimulator(range"[2,6].2")
      sim.wrap(BigDecimal(1.75)) should be (6.0)
      sim.wrap(BigDecimal(2.0))  should be (2.0)
      sim.wrap(BigDecimal(2.25)) should be (2.25)
      sim.wrap(BigDecimal(2.5))  should be (2.5)
      sim.wrap(BigDecimal(5.75)) should be (5.75)
      sim.wrap(BigDecimal(6.0))  should be (6.0)
      sim.wrap(BigDecimal(6.25))  should be (2.0)
      sim.wrap(BigDecimal(6.5))  should be (2.25)
    }
    "Should work for open ranges" in {
      val sim = ScalaIntervalSimulator(range"(2,6)")
      sim.wrap(BigDecimal(1.0)) should be (4.0)
      sim.wrap(BigDecimal(2.0)) should be (5.0)
      sim.wrap(BigDecimal(3.0)) should be (3.0)
      sim.wrap(BigDecimal(4.0)) should be (4.0)
      sim.wrap(BigDecimal(5.0)) should be (5.0)
      sim.wrap(BigDecimal(6.0)) should be (3.0)
      sim.wrap(BigDecimal(7.0)) should be (4.0)
    }
    "Should work for open ranges with binary point" in {
      val sim = ScalaIntervalSimulator(range"(2,6).2")
      sim.wrap(BigDecimal(1.75)) should be (5.5)
      sim.wrap(BigDecimal(2.0)) should be (5.75)
      sim.wrap(BigDecimal(2.25)) should be (2.25)
      sim.wrap(BigDecimal(2.5)) should be (2.5)
      sim.wrap(BigDecimal(5.75)) should be (5.75)
      sim.wrap(BigDecimal(6.0)) should be (2.25)
      sim.wrap(BigDecimal(6.25)) should be (2.5)
      sim.wrap(BigDecimal(7.0)) should be (3.25)
    }
  }
}
