// See LICENSE for license details.

package firrtlTests.stage.phases


import firrtl.{EmitAllModulesAnnotation, EmitCircuitAnnotation, HighFirrtlEmitter, VerilogCompiler}
import firrtl.annotations.NoTargetAnnotation
import firrtl.options.Phase
import firrtl.stage.{CompilerAnnotation, RunFirrtlTransformAnnotation}
import firrtl.stage.phases.AddImplicitEmitter
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class AddImplicitEmitterSpec extends AnyFlatSpec with Matchers {

  case class FooAnnotation(x: Int) extends NoTargetAnnotation
  case class BarAnnotation(x: String) extends NoTargetAnnotation

  class Fixture { val phase: Phase = new AddImplicitEmitter }

  val someAnnos = Seq(FooAnnotation(1), FooAnnotation(2), BarAnnotation("bar"))

  behavior of classOf[AddImplicitEmitter].toString

  it should "do nothing if no CompilerAnnotation is present" in new Fixture {
    phase.transform(someAnnos).toSeq should be (someAnnos)
  }

  it should "add an EmitCircuitAnnotation derived from a CompilerAnnotation" in new Fixture {
    val input = CompilerAnnotation(new VerilogCompiler) +: someAnnos
    val expected = input.flatMap{
      case a@ CompilerAnnotation(b) => Seq(a,
                                           RunFirrtlTransformAnnotation(b.emitter),
                                           EmitCircuitAnnotation(b.emitter.getClass))
      case a => Some(a)
    }
    phase.transform(input).toSeq should be (expected)
  }

  it should "not add an EmitCircuitAnnotation if an EmitAnnotation already exists" in new Fixture {
    val input = Seq(CompilerAnnotation(new VerilogCompiler),
                    EmitAllModulesAnnotation(classOf[HighFirrtlEmitter])) ++ someAnnos
    phase.transform(input).toSeq should be (input)
  }

}
