package it.com.atlassian.stash;

import com.atlassian.webdriver.bitbucket.element.FileBreadcrumbs;
import com.atlassian.webdriver.bitbucket.element.FileContent;
import com.atlassian.webdriver.bitbucket.page.FileContentPage;
import com.atlassian.webdriver.bitbucket.util.DateUtils;
import org.springframework.web.util.UriUtils;

import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.junit.Assert.*;

public abstract class BaseFileContentTest extends QARepoFuncTest {

    protected String getUrlPathComponent(String... components) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0, componentsLength = components.length; i < componentsLength; i++) {
            String component = components[i];
            String encoded;
            try {
                encoded = UriUtils.encodePathSegment(component, StandardCharsets.UTF_8.name());
            } catch (UnsupportedEncodingException e) {
                encoded = component;
            }
            if (i > 0) {
                sb.append("/");
            }
            sb.append(encoded);
        }
        return sb.toString();
    }

    protected void assertBreadcrumbs(FileBreadcrumbs breadcrumbs, String... components) {
        List<FileBreadcrumbs.Part> parts = breadcrumbs.getParts();
        assertEquals(components.length, parts.size());

        for (int i = 0, componentsLength = components.length; i < componentsLength; i++) {
            String component = components[i];
            assertEquals(component, parts.get(i).getName());
        }
    }

    protected static void assertCorrectDate(FileContentPage page, String date) {
        assertCorrectDate(page, date, Optional.empty());
    }

    protected static void assertCorrectDate(FileContentPage page, String date, Optional<? extends ZoneId> zoneId) {
        assertThat(page.getCurrentRevisionMachineDate(), DateUtils.TIME_STAMP.withTimeZone(zoneId).matchesTimestamp(date));
        assertThat(page.getCurrentRevisionDate(), DateUtils.SHORT.withTimeZone(zoneId).matchesTimestamp(date));
    }

    protected void assertLineContent(String content, FileContent.Line line) {
        assertEquals(content, line.getSourceText());
        assertFalse(line.isAdd());
        assertFalse(line.isDelete());
    }

    protected void assertLineIsAdd(String content, FileContent.Line line) {
        assertEquals(content, line.getSourceText());
        assertTrue(line.isAdd());
        assertFalse(line.isDelete());
    }

    protected void assertLineIsDelete(String content, FileContent.Line line) {
        assertEquals(content, line.getSourceText());
        assertFalse(line.isAdd());
        assertTrue(line.isDelete());
    }

    protected String getUntilRevisionFromUrl() throws URISyntaxException {
        Pattern pattern = Pattern.compile("until=([^&]+)");
        Matcher m = pattern.matcher(BITBUCKET.getTester().getDriver().getCurrentUrl());
        return m.find() ? m.group(1) : null;
    }
}
