package de.ctdo.bunti.model;

import de.ctdo.bunti.dmx.DMXChannel;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static junit.framework.Assert.*;

public class BuntiDMXDeviceTest {
    private static final int STARTADDRESS = 42;
    private static final int DEVICEID = 23;
    BuntiDMXDevice dut;

    @Before
    public void setUp() throws Exception {
        dut = new Par56Spot(DEVICEID,STARTADDRESS,"device");
    }

    @Test
    public void testGetStartAddress() throws Exception {
        assertEquals(42, dut.getStartAddress());
    }

    @Test
    public void testSetStartAddress() throws Exception {
        dut.setStartAddress(333);
        assertEquals(333, dut.getStartAddress());
    }

    @Test
    public void testSetStartAddressWrong1() throws Exception {
        assertFalse(dut.setStartAddress(0));
    }

    @Test
    public void testSetStartAddressWrong2() throws Exception {
        assertFalse(dut.setStartAddress(513));
    }


    @Test
    public void testSetValuesFromOptions() throws Exception {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put("red", 123);
        assertTrue(dut.setValuesFromOptions(options));
    }

    @Test
    public void testSetValuesFromOptionsWrong() throws Exception {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put("reddddwrong", 123);
        assertFalse(dut.setValuesFromOptions(options));
    }

    @Test
    public void testSetValuesFromOptionsWrong2() throws Exception {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put("red", null);
        assertFalse(dut.setValuesFromOptions(options));
    }

    @Test
    public void testSetChannelValueWrong() throws Exception {
        assertFalse(dut.setChannelValueByName("nonexistend", 42));
    }

    @Test
    public void testSetChannelValue() throws Exception {
        assertTrue(dut.setChannelValueByName("red", 42));
    }

    @Test
    public void testGetChannelValueOkay() throws Exception {
        assertEquals(dut.getChannelValueByName("red"), 0);
    }

    @Test
    public void testGetChannelValueWrong() throws Exception {
        assertEquals(dut.getChannelValueByName("nonexistent"), 0);
    }

    @Test
    public void testGetChannelValueWrong2() throws Exception {
        assertEquals(dut.getChannelValueByName(null), 0);
    }

    private Map<String, Object> createOptions() {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put("blue", 99);
        options.put("red", 66);
        options.put("green", 77);
        options.put("speed", 111);
        options.put("mode", 222);
        return options;
    }

    @Test
    public void testGetChannelDataCount() throws Exception {
        dut.setValuesFromOptions(createOptions());
        Map<Integer,Integer> channelData = dut.getChannelData();
        assertEquals(channelData.size(), 5);
    }

    @Test
    public void testGetChannelDataOrder() throws Exception {
        dut.setValuesFromOptions(createOptions());

        Map<Integer,Integer> channelData = dut.getChannelData();

        assertEquals(new Integer(222), channelData.get(STARTADDRESS));
        assertEquals(new Integer(66),  channelData.get(STARTADDRESS + 1));
        assertEquals(new Integer(77),  channelData.get(STARTADDRESS + 2));
        assertEquals(new Integer(99),  channelData.get(STARTADDRESS + 3));
        assertEquals(new Integer(111), channelData.get(STARTADDRESS + 4));
    }
    
//    @Test
//    public void testGetChannelDataIndex() throws Exception {
//        dut = new Par56Spot(42, -10, "faultdevice");
//        dut.setChannelValueByName("red", 23);
//        assertEquals(5, dut.getChannelData().size());
//    }

    @Test
    public void testAddChannel() throws Exception {
        dut.addChannel(new DMXChannel(5, "channel"));
        Map<Integer,Integer> channelData = dut.getChannelData();
        assertEquals(6, channelData.size());
    }

    @Test
    public void testSetDeviceName() throws Exception {
        dut.setDeviceName("rapunzel");
        assertEquals("rapunzel", dut.getDeviceName());
    }
    
    @Test
    public void testGetDeviceId() throws Exception {
        assertEquals(DEVICEID, dut.getDeviceId());
    }

}
