package com.atlassian.stash.internal.sal.user;

import com.atlassian.sal.api.usersettings.UserSettingsService;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Test;

import static org.junit.Assert.*;

public class DelegatingUserSettingsTest {

    private static final String KEY_TOO_LONG = RandomStringUtils.random(UserSettingsService.MAX_KEY_LENGTH + 1);
    private static final String VALUE_TOO_LONG = RandomStringUtils.random(UserSettingsService.MAX_STRING_VALUE_LENGTH + 1);

    @Test
    public void testGetBoolean() {
        DelegatingUserSettings settings = new MapUserSettingsBuilder()
                .put("bool", true)
                .put("str", "foo")
                .put("int", 5)
                .build();
        assertEquals(true, settings.getBoolean("bool").get());
        assertEquals(null, settings.getBoolean("fake").getOrNull());
    }

    @Test
    public void testGetBooleanAsString() {
        assertEquals(Boolean.TRUE, createSettings("true").getBoolean("value").get());
    }

    @Test
    public void testGetBooleanAsStringBad() {
        assertEquals(Boolean.FALSE, createSettings("bad").getBoolean("value").get());
    }

    @Test
    public void testGetBooleanAsStringNull() {
        assertNull(createNullSettings().getBoolean("value").getOrNull());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetBooleanKeyTooLong() {
        createNullSettings().getBoolean(KEY_TOO_LONG);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetBooleanNullKey() {
        createNullSettings().getBoolean(null);
    }

    @Test
    public void testGetLong() {
        assertEquals(Long.valueOf(5), createSettings(5).getLong("value").get());
    }

    @Test
    public void testGetLongAsString() {
        assertEquals(Long.valueOf(5), createSettings("5").getLong("value").get());
    }

    @Test
    public void testGetLongAsStringBad() {
        assertFalse(createSettings("bad").getLong("value").isDefined());
    }

    @Test
    public void testGetLongAsStringNull() {
        assertNull(createNullSettings().getLong("value").getOrNull());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetLongKeyTooLong() {
        createNullSettings().getLong(KEY_TOO_LONG);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetLongNullKey() {
        createNullSettings().getLong(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetStringKeyTooLong() {
        createNullSettings().getString(KEY_TOO_LONG);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetStringNullKey() {
        createNullSettings().getString(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPutStringKeyTooLong() {
        new MapUserSettingsBuilder().put(KEY_TOO_LONG, "value");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPutBooleanKeyTooLong() {
        new MapUserSettingsBuilder().put(KEY_TOO_LONG, true);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPutLongKeyTooLong() {
        new MapUserSettingsBuilder().put(KEY_TOO_LONG, 123L);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPutStringKeyNull() {
        new MapUserSettingsBuilder().put(null, "value");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPutBooleanKeyNull() {
        new MapUserSettingsBuilder().put(null, true);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPutLongKeyNull() {
        new MapUserSettingsBuilder().put(null, 123L);
    }

    @Test(expected = IllegalArgumentException.class)
     public void testPutStringValueTooLong() {
        new MapUserSettingsBuilder().put("key", VALUE_TOO_LONG);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPutStringValueNull() {
        new MapUserSettingsBuilder().put("key", null);
    }

    private DelegatingUserSettings createNullSettings() {
        return new MapUserSettingsBuilder().build();
    }

    private DelegatingUserSettings createSettings(Object value) {
        return new MapUserSettingsBuilder().put("value", "" + value).build();
    }
}
