package it.com.atlassian.stash;

import com.atlassian.bitbucket.hamcrest.OptionalMatcher;
import com.atlassian.webdriver.bitbucket.element.TimeZoneSelector;
import com.atlassian.webdriver.bitbucket.page.UserAccountSettingsPage;
import org.hamcrest.Matchers;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

import java.time.ZoneId;
import java.util.Locale;
import java.util.Optional;

import static com.atlassian.bitbucket.hamcrest.OptionalMatcher.empty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

/**
 * Test updating the user details (display name, email address, etc.) in the User Account page.
 *
 * @see it.com.atlassian.stash.UserAvatarFormTest
 * @see it.com.atlassian.stash.admin.UserUpdateRightsTest
 */
public class UserAccountDetailsTest extends BaseBrowserFuncTest {

    private static final String USERNAME = "accountDetailsTestUser";
    private static final String ORIG_DISPLAY_NAME = "Original Display Name";
    private static final String ORIG_EMAIL_ADDRESS = "original@email.address";
    private static final String NEW_DISPLAY_NAME = "New Display Name";
    private static final String NEW_EMAIL_ADDRESS = "new@email.address";

    @BeforeClass
    public static void createUser() {
        getClassTestContext().user(USERNAME, ORIG_DISPLAY_NAME, USERNAME, ORIG_EMAIL_ADDRESS);
    }

    @Test
    public void testUpdateDetails() {
        UserAccountSettingsPage page = loginAs(USERNAME, USERNAME, UserAccountSettingsPage.class);
        page.setDisplayName(NEW_DISPLAY_NAME);
        page.setEmailAddress(NEW_EMAIL_ADDRESS);
        page.getLocale().searchAndSelect("Zealand");
        page = page.submit();

        assertEquals(NEW_DISPLAY_NAME, page.getDisplayName());
        assertEquals(NEW_EMAIL_ADDRESS, page.getEmailAddress());
        assertEquals(new Locale("en", "NZ").toString(), page.getLocale().getLocale());
        // Don't really make sense in the page object
        WebDriver driver = BITBUCKET.getTester().getDriver();
        // We have overridden the title on the page in the browser's "plugin" for NZ only - and this is the proof that
        // switching to a different locale works immediately and correctly
        assertThat(driver.findElement(By.cssSelector(".aui-page-panel-content .aui-page-header-main")).getText(), Matchers.equalTo("Account settings NZ Title"));
    }

    @Test
    public void testUserTimeZone() {
        UserAccountSettingsPage page = loginAs(USERNAME, USERNAME, UserAccountSettingsPage.class);
        TimeZoneSelector zoneSelector = page.getTimeZoneSelector();
        ZoneId expectedTimeZone = ZoneId.of("Africa/Cairo");

        try {
            assertThat(zoneSelector.getTimeZone(), empty());

            zoneSelector.filter("Cairo");
            zoneSelector.setTimeZone(expectedTimeZone);
            page = page.submit();
            zoneSelector = page.getTimeZoneSelector();

            Optional<ZoneId> actualTimeZone = zoneSelector.getTimeZone();
            assertThat(actualTimeZone, OptionalMatcher.some(expectedTimeZone));

            zoneSelector.clearTimeZone();
            page = page.submit();
            zoneSelector = page.getTimeZoneSelector();

            actualTimeZone = zoneSelector.getTimeZone();
            assertThat(actualTimeZone, empty());
        } finally {
            restoreTimeZone();
        }
    }

    private void restoreTimeZone() {
        try {
            TimeZoneTestHelper.setUserTimeZone(Optional.empty(), USERNAME, USERNAME);
        } catch (Exception e) {
            // do nothing, in case the test has already thrown an exception (to prevent masking the original error)
            // (here we assume that any exception in the parent test implies that the settings were not persisted)
        }
    }
}
