package com.flagship.abox.manager.testing.fakes

import com.flagship.abox.manager.domain.DeviceName
import com.flagship.abox.manager.domain.DomainError
import com.flagship.abox.manager.domain.DomainResult
import com.flagship.abox.manager.domain.InfraredCode
import com.flagship.abox.manager.domain.ProviderProfileId
import com.flagship.abox.manager.domain.SocketPowerState
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class FakeDeviceGatewaysTest {
    private val profileOne = ProviderProfileId("one")
    private val profileTwo = ProviderProfileId("two")
    private val socket = DeviceName("socket-1")

    @Test
    fun socketStateChangesWithoutCrossingProviderBoundary() = runTest {
        val gateway = FakeSocketGateway()

        gateway.setPower(profileOne, socket, SocketPowerState.ON)

        val one = gateway.getStatus(profileOne, socket) as DomainResult.Success
        val two = gateway.getStatus(profileTwo, socket) as DomainResult.Success
        assertEquals(SocketPowerState.ON, one.value.powerState)
        assertEquals(SocketPowerState.OFF, two.value.powerState)
    }

    @Test
    fun temperatureGatewaySupportsNoDataAndErrors() = runTest {
        val gateway = FakeTemperatureHumidityGateway()
        gateway.setError(profileOne, DeviceName("empty"), DomainError.NoData())
        gateway.setError(profileOne, DeviceName("offline"), DomainError.DeviceOffline())

        assertTrue(gateway.getReading(profileOne, DeviceName("empty")) is DomainResult.Failure)
        assertTrue(gateway.getReading(profileOne, DeviceName("offline")) is DomainResult.Failure)
        assertTrue(gateway.getReading(profileOne, DeviceName("th-1")) is DomainResult.Success)
    }

    @Test
    fun infraredGatewayRecordsCallsAndResults() = runTest {
        val gateway = FakeInfraredGateway()
        val deviceName = DeviceName("ir-1")
        val code = InfraredCode(deviceName, "power", "code-value")

        gateway.sendKey(profileOne, deviceName, "power")
        gateway.learnKey(profileOne, deviceName, "volume-up")
        val download = gateway.downloadCodes(profileOne, listOf(code))

        assertEquals(InfraredCall(profileOne, deviceName, "power"), gateway.sentKeys.single())
        assertEquals("volume-up", gateway.learnedKeys.single().key)
        assertEquals(InfraredDownloadCall(profileOne, listOf(code)), gateway.downloadCalls.single())
        assertTrue(download is DomainResult.Success)
    }
}
