// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package org.wpilib.simulation;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
import org.wpilib.hardware.discrete.DigitalOutput;
import org.wpilib.hardware.hal.HAL;
import org.wpilib.simulation.testutils.BooleanCallback;
import org.wpilib.simulation.testutils.DoubleCallback;
import org.wpilib.simulation.testutils.IntCallback;

class DigitalPWMSimTest {
  @Test
  void testInitialization() {
    try (DigitalOutput output = new DigitalOutput(0)) {
      DigitalPWMSim sim = new DigitalPWMSim(output);
      assertFalse(sim.getInitialized());

      BooleanCallback initializeCallback = new BooleanCallback();
      DoubleCallback dutyCycleCallback = new DoubleCallback();
      try (CallbackStore initCb = sim.registerInitializedCallback(initializeCallback, false);
          CallbackStore dutyCycleCb = sim.registerDutyCycleCallback(dutyCycleCallback, false)) {
        final double kTestDutyCycle = 0.191;
        output.enablePWM(kTestDutyCycle);

        assertTrue(sim.getInitialized());
        assertTrue(initializeCallback.wasTriggered());
        assertTrue(initializeCallback.getSetValue());

        assertEquals(kTestDutyCycle, sim.getDutyCycle());
        assertTrue(dutyCycleCallback.wasTriggered());
        assertEquals(kTestDutyCycle, dutyCycleCallback.getSetValue());
      }
    }
  }

  @Test
  void setPinTest() {
    HAL.initialize(500, 0);

    try (DigitalOutput output = new DigitalOutput(0)) {
      DigitalPWMSim sim = new DigitalPWMSim(output);
      IntCallback callback = new IntCallback();
      try (CallbackStore cb = sim.registerPinCallback(callback, false)) {
        sim.setPin(191);
        assertEquals(191, sim.getPin());
        assertTrue(callback.wasTriggered());
        assertEquals(191, callback.getSetValue());
      }
    }
  }
}
