
class TestFreshnessPage extends PageWithHeading {
    constructor(summaryPageConfiguration, testAgeToleranceInHours)
    {
        super('test-freshness', null);
        this._testAgeTolerance = (testAgeToleranceInHours || 24) * 3600 * 1000;
        this._timeDuration = this._testAgeTolerance * 2;
        this._excludedConfigurations = {};
        this._lastDataPointByConfiguration = null;
        this._indicatorByConfiguration = null;
        this._renderTableLazily = new LazilyEvaluatedFunction(this._renderTable.bind(this));
        this._hoveringIndicator = null;
        this._indicatorForTooltip = null;
        this._firstIndicatorAnchor = null;
        this._showTooltip = false;
        this._builderByIndicator = null;
        this._tabIndexForIndicator = null;
        this._coordinateForIndicator = null;
        this._indicatorAnchorGrid = null;
        this._skipNextClick = false;
        this._skipNextStateCleanOnScroll = false;
        this._lastFocusedCell = null;
        this._renderTooltipLazily = new LazilyEvaluatedFunction(this._renderTooltip.bind(this));

        this._loadConfig(summaryPageConfiguration);
    }

    name() { return 'Test-Freshness'; }

    _loadConfig(summaryPageConfiguration)
    {
        const platformIdSet = new Set;
        const metricIdSet = new Set;

        for (const config of summaryPageConfiguration) {
            for (const platformGroup of config.platformGroups) {
                for (const platformId of platformGroup.platforms)
                    platformIdSet.add(platformId);
            }

            for (const metricGroup of config.metricGroups) {
                for (const subgroup of metricGroup.subgroups) {
                    for (const metricId of subgroup.metrics)
                        metricIdSet.add(metricId);
                }
            }

            const excludedConfigs = config.excludedConfigurations;
            for (const platform in excludedConfigs) {
                if (platform in this._excludedConfigurations)
                    this._excludedConfigurations[platform] = this._excludedConfigurations[platform].concat(excludedConfigs[platform]);
                else
                    this._excludedConfigurations[platform] = excludedConfigs[platform];
            }
        }
        this._platforms = [...platformIdSet].map((platformId) => Platform.findById(platformId));
        this._metrics = [...metricIdSet].map((metricId) => Metric.findById(metricId));
    }

    open(state)
    {
        this._fetchTestResults();
        super.open(state);
    }

    didConstructShadowTree()
    {
        super.didConstructShadowTree();

        const tooltipTable = this.content('tooltip-table');
        this.content().addEventListener('click', (event) => {
            if (!tooltipTable.contains(event.target))
                this._clearIndicatorState(false);
        });

        tooltipTable.onkeydown = this.createEventHandler((event) => {
            if (event.code == 'Escape') {
                event.preventDefault();
                event.stopPropagation();
                this._lastFocusedCell.focus({preventScroll: true});
            }
        }, {preventDefault: false, stopPropagation: false});

        window.addEventListener('keydown', (event) => {
            if (!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.code))
                return;

            event.preventDefault();
            if (!this._indicatorForTooltip && !this._hoveringIndicator) {
                if (this._firstIndicatorAnchor)
                    this._firstIndicatorAnchor.focus({preventScroll: true});
                return;
            }

            let [row, column] = this._coordinateForIndicator.get(this._indicatorForTooltip || this._hoveringIndicator);
            let direction = null;

            switch (event.code) {
                case 'ArrowUp':
                    row -= 1;
                    break;
                case 'ArrowDown':
                    row += 1;
                    break;
                case 'ArrowLeft':
                    column -= 1;
                    direction = 'leftOnly'
                    break;
                case 'ArrowRight':
                    column += 1;
                    direction = 'rightOnly'
            }

            const closestIndicatorAnchor = this._findClosestIndicatorAnchorForCoordinate(column, row, this._indicatorAnchorGrid, direction);
            if (closestIndicatorAnchor)
                closestIndicatorAnchor.focus({preventScroll: true});
        });
    }

    _findClosestIndicatorAnchorForCoordinate(columnIndex, rowIndex, grid, direction)
    {
        rowIndex = Math.min(Math.max(rowIndex, 0), grid.length - 1);
        const row = grid[rowIndex];
        if (!row.length)
            return null;

        const start = Math.min(Math.max(columnIndex, 0), row.length - 1);
        if (row[start])
            return row[start];

        let offset = 1;
        while (true) {
            const leftIndex = start - offset;
            if (leftIndex >= 0 && row[leftIndex] && direction != 'rightOnly')
                return row[leftIndex];
            const rightIndex = start + offset;
            if (rightIndex < row.length && row[rightIndex] && direction != 'leftOnly')
                return row[rightIndex];
            if (leftIndex < 0 && rightIndex >= row.length)
                break;
            offset += 1;
        }
        return null;
    }

    _fetchTestResults()
    {
        this._measurementSetFetchTime = Date.now();
        this._lastDataPointByConfiguration = new Map;
        this._builderByIndicator = new Map;

        const startTime = this._measurementSetFetchTime - this._timeDuration;

        for (const platform of this._platforms) {
            const lastDataPointByMetric = new Map;
            this._lastDataPointByConfiguration.set(platform, lastDataPointByMetric);

            for (const metric of this._metrics) {
                if (!this._isValidPlatformMetricCombination(platform, metric, this._excludedConfigurations))
                    continue;

                const measurementSet = MeasurementSet.findSet(platform.id(), metric.id(), platform.lastModified(metric));
                measurementSet.fetchBetween(startTime, this._measurementSetFetchTime).then(() => {
                    const currentTimeSeries = measurementSet.fetchedTimeSeries('current', false, false);

                    let timeForLatestBuild = startTime;
                    let lastBuild = null;
                    let builder = null;
                    let commitSetOfLastPoint = null;
                    const lastPoint = currentTimeSeries.lastPoint();
                    if (lastPoint) {
                        timeForLatestBuild = lastPoint.build().buildTime().getTime();
                        const view = currentTimeSeries.viewBetweenPoints(currentTimeSeries.firstPoint(), lastPoint);
                        for (const point of view) {
                            const build = point.build();
                            if (!build)
                                continue;
                            if (build.buildTime().getTime() >= timeForLatestBuild) {
                                timeForLatestBuild = build.buildTime().getTime();
                                lastBuild = build;
                                builder = build.builder();
                            }
                        }
                        commitSetOfLastPoint = lastPoint.commitSet();
                    }

                    lastDataPointByMetric.set(metric, {time: timeForLatestBuild, hasCurrentDataPoint: !!lastPoint,
                        lastBuild, builder, commitSetOfLastPoint});
                    this.enqueueToRender();
                });
            }
        }
    }

    render()
    {
        super.render();

        this._renderTableLazily.evaluate(this._platforms, this._metrics);

        let buildSummaryForFocusingIndicator = null;
        let buildForFocusingIndicator = null;
        let commitSetForFocusingdIndicator = null;
        let chartURLForFocusingIndicator = null;
        let platformForFocusingIndicator = null;
        let metricForFocusingIndicator = null;
        const builderForFocusingIndicator = this._indicatorForTooltip ? this._builderByIndicator.get(this._indicatorForTooltip) : null;
        const builderForHoveringIndicator = this._hoveringIndicator ? this._builderByIndicator.get(this._hoveringIndicator) : null;
        for (const [platform, lastDataPointByMetric] of this._lastDataPointByConfiguration.entries()) {
            for (const [metric, lastDataPoint] of lastDataPointByMetric.entries()) {
                const timeDuration = this._measurementSetFetchTime - lastDataPoint.time;
                const timeDurationSummaryPrefix = lastDataPoint.hasCurrentDataPoint ? '' : 'More than ';
                const timeDurationSummary = BuildRequest.formatTimeInterval(timeDuration);
                const summary = `${timeDurationSummaryPrefix}${timeDurationSummary} since latest data point.`;

                const indicator = this._indicatorByConfiguration.get(platform).get(metric);
                if (this._indicatorForTooltip && this._indicatorForTooltip === indicator) {
                    buildSummaryForFocusingIndicator = summary;
                    buildForFocusingIndicator = lastDataPoint.lastBuild;
                    commitSetForFocusingdIndicator = lastDataPoint.commitSetOfLastPoint;
                    chartURLForFocusingIndicator =  this._router.url('charts', ChartsPage.createStateForDashboardItem(platform.id(), metric.id(),
                        this._measurementSetFetchTime - this._timeDuration));
                    platformForFocusingIndicator = platform;
                    metricForFocusingIndicator = metric;
                }
                this._builderByIndicator.set(indicator, lastDataPoint.builder);
                const highlighted = builderForFocusingIndicator && builderForFocusingIndicator == lastDataPoint.builder
                    || builderForHoveringIndicator && builderForHoveringIndicator === lastDataPoint.builder;
                indicator.update(timeDuration, this._testAgeTolerance, highlighted);
            }
        }
        this._renderTooltipLazily.evaluate(this._indicatorForTooltip, this._showTooltip, buildSummaryForFocusingIndicator, buildForFocusingIndicator,
            commitSetForFocusingdIndicator, chartURLForFocusingIndicator, platformForFocusingIndicator, metricForFocusingIndicator, this._tabIndexForIndicator.get(this._indicatorForTooltip));
    }

    _renderTooltip(indicator, showTooltip, buildSummary, build, commitSet, chartURL, platform, metric, tabIndex)
    {
        if (!indicator || !buildSummary || !showTooltip) {
            this.content('tooltip-anchor').style.display =  showTooltip ? null : 'none';
            return;
        }
        const element = ComponentBase.createElement;
        const link = ComponentBase.createLink;

        const rect = indicator.element().getBoundingClientRect();
        const tooltipAnchor = this.content('tooltip-anchor');
        tooltipAnchor.style.display = null;
        tooltipAnchor.style.top = rect.top + 'px';
        tooltipAnchor.style.left = rect.left + rect.width / 2 + 'px';

        let tableContent = [element('tr', element('td', {colspan: 2}, buildSummary))];

        if (chartURL) {
            const linkDescription = `${metric.test().name()} on ${platform.name()}`;
            tableContent.push(element('tr', [
                element('td', 'Chart'),
                element('td', {colspan: 2}, link(linkDescription, linkDescription, chartURL, true, tabIndex))
            ]));
        }

        if (commitSet) {
            if (commitSet.repositories().length)
                tableContent.push(element('tr', element('th', {colspan: 2}, 'Latest build information')));

            tableContent.push(Repository.sortByNamePreferringOnesWithURL(commitSet.repositories()).map((repository) => {
                const commit = commitSet.commitForRepository(repository);
                return element('tr', [
                    element('td', repository.name()),
                    element('td', commit.url() ? link(commit.label(), commit.label(), commit.url(), true, tabIndex) : commit.label())
                ]);
            }));
        }

        if (build) {
            const url = build.url();
            const buildNumber = build.buildNumber();
            tableContent.push(element('tr', [
                element('td', 'Build'),
                element('td', {colspan: 2}, [
                    url ? link(buildNumber, build.label(), url, true, tabIndex) : buildNumber
                ]),
            ]));
        }

        this.renderReplace(this.content("tooltip-table"),  tableContent);
    }

    _renderTable(platforms, metrics)
    {
        const element = ComponentBase.createElement;
        const tableHeadElements = [element('th',  {class: 'table-corner row-head'}, 'Platform \\ Test')];

        for (const metric of metrics)
            tableHeadElements.push(element('th', {class: 'diagonal-head'}, element('div', metric.test().fullName())));

        this._indicatorByConfiguration = new Map;
        this._coordinateForIndicator = new Map;
        this._tabIndexForIndicator = new Map;
        this._indicatorAnchorGrid = [];
        this._firstIndicatorAnchor = null;
        let currentTabIndex = 1;

        const tableBodyElement = platforms.map((platform, rowIndex) =>  {
            const indicatorByMetric = new Map;
            this._indicatorByConfiguration.set(platform, indicatorByMetric);

            let indicatorAnchorsInCurrentRow = [];

            const cells = metrics.map((metric, columnIndex) => {
                const [cell, anchor, indicator] = this._constructTableCell(platform, metric, currentTabIndex);

                indicatorAnchorsInCurrentRow.push(anchor);
                if (!indicator)
                    return cell;

                indicatorByMetric.set(metric, indicator);
                this._tabIndexForIndicator.set(indicator, currentTabIndex);
                this._coordinateForIndicator.set(indicator, [rowIndex, columnIndex]);

                ++currentTabIndex;
                if (!this._firstIndicatorAnchor)
                    this._firstIndicatorAnchor = anchor;
                return cell;
            });
            this._indicatorAnchorGrid.push(indicatorAnchorsInCurrentRow);

            const row = element('tr', [element('th', {class: 'row-head'}, platform.label()), ...cells]);
            return row;
        });

        const tableBody = element('tbody', tableBodyElement);
        tableBody.onscroll = this.createEventHandler(() => this._clearIndicatorState(true));

        this.renderReplace(this.content('test-health'), [element('thead', tableHeadElements), tableBody]);
    }

    _isValidPlatformMetricCombination(platform, metric)
    {
        return !(this._excludedConfigurations && this._excludedConfigurations[platform.id()]
            && this._excludedConfigurations[platform.id()].some((metricId) => metricId == metric.id()))
            && platform.hasMetric(metric);
    }

    _constructTableCell(platform, metric, tabIndex)
    {
        const element = ComponentBase.createElement;
        const link = ComponentBase.createLink;
        if (!this._isValidPlatformMetricCombination(platform, metric))
            return [element('td', {class: 'blank-cell'}, element('div')), null, null];

        const indicator = new FreshnessIndicator;
        const anchor = link(indicator, '', () => {
            if (this._skipNextClick) {
                this._skipNextClick = false;
                return;
            }
            this._showTooltip = !this._showTooltip;
            this.enqueueToRender();
        }, false, tabIndex);

        const cell = element('td', {class: 'status-cell'}, anchor);
        this._configureAnchorForIndicator(anchor, indicator);
        return [cell, anchor, indicator];
    }

    _configureAnchorForIndicator(anchor, indicator)
    {
        anchor.onmouseover = this.createEventHandler(() => {
            this._hoveringIndicator = indicator;
            this.enqueueToRender();
        });
        anchor.onmousedown = this.createEventHandler(() =>
            this._skipNextClick = this._indicatorForTooltip != indicator, {preventDefault: false, stopPropagation: false});
        anchor.onfocus = this.createEventHandler(() => {
            this._showTooltip = this._indicatorForTooltip != indicator;
            this._hoveringIndicator = indicator;
            this._indicatorForTooltip = indicator;
            this._lastFocusedCell = anchor;
            this._skipNextStateCleanOnScroll = true;
            this.enqueueToRender();
        });
        anchor.onkeydown = this.createEventHandler((event) => {
            if (event.code == 'Escape') {
                event.preventDefault();
                event.stopPropagation();
                this._showTooltip = event.code == 'Enter' ? !this._showTooltip : false;
                this.enqueueToRender();
            }
        }, {preventDefault: false, stopPropagation: false});
    }

    _clearIndicatorState(dueToScroll)
    {
        if (this._skipNextStateCleanOnScroll) {
            this._skipNextStateCleanOnScroll = false;
            if (dueToScroll)
                return;
        }
        this._showTooltip = false;
        this._indicatorForTooltip = null;
        this._hoveringIndicator = null;
        this.enqueueToRender();
    }

    static htmlTemplate()
    {
        return `<section class="page-with-heading">
            <table id="test-health"></table>
            <div id="tooltip-anchor">
                <table id="tooltip-table"></table>
            </div>
        </section>`;
    }

    static cssTemplate()
    {
        return `
            .page-with-heading {
                display: flex;
                justify-content: center;
            }
            #test-health {
                font-size: 1rem;
            }
            #test-health thead {
                display: block;
                align: right;
            }
            #test-health th.table-corner {
                text-align: right;
                vertical-align: bottom;
            }
            #test-health .row-head {
                min-width: 15.5rem;
            }
            #test-health th {
                text-align: left;
                border-bottom: 0.1rem solid #ccc;
                font-weight: normal;
            }
            #test-health th.diagonal-head {
                white-space: nowrap;
                height: 16rem;
                width: 2.2rem;
                border-bottom: 0rem;
                padding: 0;
            }
            #test-health th.diagonal-head > div {
                transform: translate(1.1rem, 7.5rem) rotate(315deg);
                transform-origin: center left;
                width: 2.2rem;
                border: 0rem;
            }
            #test-health tbody {
                display: block;
                overflow: auto;
                height: calc(100vh - 24rem);
            }
            #test-health td.status-cell {
                position: relative;
                margin: 0;
                padding: 0;
                max-width: 2.2rem;
                max-height: 2.2rem;
                min-width: 2.2rem;
                min-height: 2.2rem;
            }
            #test-health td.status-cell>a {
                display: block;
            }
            #test-health td.status-cell>a:focus {
                outline: none;
            }
            #test-health td.status-cell>a:focus::after {
                position: absolute;
                content: "";
                bottom: -0.1rem;
                left: 50%;
                margin-left: -0.2rem;
                height: 0rem;
                border-width: 0.2rem;
                border-style: solid;
                border-color: transparent transparent red transparent;
                outline: none;
            }
            #test-health td.blank-cell {
                margin: 0;
                padding: 0;
                max-width: 2.2rem;
                max-height: 2.2rem;
                min-width: 2.2rem;
                min-height: 2.2rem;
            }
            #test-health td.blank-cell > div  {
                background-color: #F9F9F9;
                height: 1.6rem;
                width: 1.6rem;
                margin: auto;
                padding: 0;
                position: relative;
                overflow: hidden;
            }
            #test-health td.blank-cell > div::before {
                content: "";
                position: absolute;
                top: -1px;
                left: -1px;
                display: block;
                width: 0px;
                height: 0px;
                border-right: calc(1.6rem + 1px) solid #ddd;
                border-top: calc(1.6rem + 1px) solid transparent;
            }
            #test-health td.blank-cell > div::after {
                content: "";
                display: block;
                position: absolute;
                top: 1px;
                left: 1px;
                width: 0px;
                height: 0px;
                border-right: calc(1.6rem - 1px) solid #F9F9F9;
                border-top: calc(1.6rem - 1px) solid transparent;
            }
            #tooltip-anchor {
                width: 0;
                height: 0;
                position: absolute;
            }
            #tooltip-table {
                position: absolute;
                width: 22rem;
                background-color: #696969;
                opacity: 0.96;
                margin: 0.3rem;
                padding: 0.3rem;
                border-radius: 0.4rem;
                z-index: 1;
                text-align: center;
                display: inline-table;
                color: white;
                bottom: 0;
                left: -11.3rem;
            }
            #tooltip-table td {
                overflow: hidden;
                max-width: 22rem;
                text-overflow: ellipsis;
            }
            #tooltip-table::after {
                content: " ";
                position: absolute;
                top: 100%;
                left: 50%;
                margin-left: -0.3rem;
                border-width: 0.3rem;
                border-style: solid;
                border-color: #696969 transparent transparent transparent;
            }
            #tooltip-table a {
                color: white;
                font-weight: bold;
            }
            #tooltip-table a:focus {
                background-color: #AAB7B8;
                outline: none;
            }
        `;
    }

    routeName() { return 'test-freshness'; }
}