package com.atlassian.webdriver.bitbucket.page.admin.repo;

import com.atlassian.pageobjects.elements.PageElement;
import com.atlassian.pageobjects.elements.query.Poller;
import com.atlassian.pageobjects.elements.query.Queries;
import com.atlassian.webdriver.bitbucket.element.Avatar;
import com.atlassian.webdriver.bitbucket.page.BaseRepositoryPage;
import com.atlassian.webdriver.bitbucket.util.DateUtils;
import com.atlassian.webdriver.bitbucket.util.ElementUtils;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.Lists;
import org.hamcrest.Matchers;
import org.openqa.selenium.By;

import java.time.Instant;
import java.util.List;

public class AuditPage extends BaseRepositoryPage {

    private static final String AUDIT_TABLE_CLASS = "audit-log-table";

    public AuditPage(String projectKey, String repositorySlug) {
        super(projectKey, repositorySlug);
    }

    @Override
    public String getUrl() {
        return String.format("/plugins/servlet/audit-log/%s/%s", projectKey, slug);
    }

    public boolean isEmpty() {
        return elementFinder.find(By.className("audit-log-empty")).isPresent();
    }

    public List<AuditRow> getEntries() {
        return getHooks(By.cssSelector("." + AUDIT_TABLE_CLASS + " tbody tr"));
    }

    private List<AuditRow> getHooks(By selector) {
        return Lists.newArrayList(Lists.transform(elementFinder.findAll(selector), new Function<PageElement, AuditRow>() {
            public AuditRow apply(PageElement row) {
                return pageBinder.bind(AuditRow.class, row);
            }
        }));
    }

    public void scroll() {
        ElementUtils.scrollDocumentAndWait(elementFinder.find(By.className(AUDIT_TABLE_CLASS)));
    }

    public void scrollUntilNoMoreResults() {
        Poller.waitUntil(Queries.forSupplier(timeouts, new Supplier<PageElement>() {
            @Override
            public PageElement get() {
                scroll();
                return elementFinder.find(By.className("no-more-results"), PageElement.class);
            }
        }), Matchers.notNullValue(PageElement.class));
    }

    public static class AuditRow {

        private final PageElement element;

        public AuditRow(PageElement element) {
            this.element = element;
        }

        public Avatar getUser() {
            return element.find(By.className("cell-username")).find(By.className(Avatar.CLASS_NAME), Avatar.class);
        }

        public String getAction() {
            return element.find(By.className("cell-action")).getText();
        }

        public String getDetails() {
            return element.find(By.className("cell-details")).getText();
        }

        public Instant getTimestamp() {
            return DateUtils.parseServerTimestamp(element.find(By.className("cell-timestamp")).getAttribute("datetime")).toInstant();
        }

        private void click() {
            element.click();
        }
    }

}
