package io.openems.edge.io.shelly.shelly25;

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

import org.junit.jupiter.api.Test;

import io.openems.common.bridge.http.api.HttpError;
import io.openems.common.bridge.http.api.HttpResponse;
import io.openems.common.bridge.http.dummy.DummyBridgeHttpBundle;
import io.openems.edge.bridge.http.cycle.HttpBridgeCycleServiceDefinition;
import io.openems.edge.bridge.http.cycle.dummy.DummyCycleSubscriber;
import io.openems.edge.common.test.AbstractComponentTest.TestCase;
import io.openems.edge.common.test.ComponentTest;

public class IoShelly25ImplTest {

	@Test
	public void test() throws Exception {
		final var sut = new IoShelly25Impl();
		final var httpTestBundle = DummyBridgeHttpBundle.of();
		final var dummyCycleSubscriber = new DummyCycleSubscriber();
		new ComponentTest(sut) //
				.addReference("httpBridgeFactory", httpTestBundle.factory()) //
				.addReference("httpBridgeCycleServiceDefinition",
						new HttpBridgeCycleServiceDefinition(dummyCycleSubscriber)) //
				.activate(MyConfig.create() //
						.setId("io0") //
						.setIp("127.0.0.1") //
						.build()) //

				// Test case for a successful JSON response
				.next(new TestCase("Successful read response") //
						.onBeforeProcessImage(() -> {
							httpTestBundle.forceNextSuccessfulResult(HttpResponse.ok("""
										{
											"relays": [
												{
													"ison": true,
													"overtemperature": false,
													"overpower": false
												},
												{
													"ison": false,
													"overtemperature": true,
													"overpower": true
												}
											]
										}
									"""));
							dummyCycleSubscriber.triggerNextCycle();
						}) //
						.onAfterProcessImage(() -> assertEquals("x -", sut.debugLog())) //

						.output(IoShelly25.ChannelId.RELAY_1, null) // expecting WriteValue
						.output(IoShelly25.ChannelId.RELAY_1_OVERPOWER, false) //
						.output(IoShelly25.ChannelId.RELAY_1_OVERTEMP, false) //
						.output(IoShelly25.ChannelId.RELAY_2, null) // expecting WriteValue
						.output(IoShelly25.ChannelId.RELAY_2_OVERPOWER, true) //
						.output(IoShelly25.ChannelId.RELAY_2_OVERTEMP, true) //
						.output(IoShelly25.ChannelId.SLAVE_COMMUNICATION_FAILED, false)) //

				// Test case for an invalid JSON response
				.next(new TestCase("Invalid read response") //
						.onBeforeProcessImage(() -> { //
							httpTestBundle.forceNextFailedResult(HttpError.ResponseError.notFound());
							dummyCycleSubscriber.triggerNextCycle();
						}) //
						.onAfterProcessImage(() -> assertEquals("? ?", sut.debugLog())) //

						.output(IoShelly25.ChannelId.RELAY_1, null) // expecting WriteValue
						.output(IoShelly25.ChannelId.RELAY_1_OVERPOWER, null) //
						.output(IoShelly25.ChannelId.RELAY_1_OVERTEMP, null) //
						.output(IoShelly25.ChannelId.RELAY_2, null) // expecting WriteValue
						.output(IoShelly25.ChannelId.RELAY_2_OVERPOWER, null) //
						.output(IoShelly25.ChannelId.RELAY_2_OVERTEMP, null) //
						.output(IoShelly25.ChannelId.SLAVE_COMMUNICATION_FAILED, true)) //

				.deactivate();//
	}
}