# Copyright 2026 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import asyncio
import os
import tempfile
from contextlib import ExitStack

from .. import trace

__FCP_HISTOGRAM_NAME = "PageLoad.PaintTiming.NavigationToFirstContentfulPaint"


async def measure_fcp(app, url, trace_file=None, trace_config=None):
    """Measures FCP to navigate to `url` by checking the value recorded into
    `PageLoad.PaintTiming.NavigationToFirstContentfulPaint`

    See `tools/metrics/histograms/metadata/page/histograms.xml` for more
    details about when the metric is recorded.

    This function performs a navigation to `url` while recording a trace and
    then queries the trace for the histogram value. The navigation starts from
    the currently open page.

    Args:
        app: The chrome.App object with which to start and stop chrome
        url: The URL to navigate to.
        trace_file: An optional `trace.TraceFile` object to store the trace.
                    If not provided, a temporary file will be created.
        trace_config: An optional path to a Perfetto trace config file.
                      If not provided, a default config is used.

    Returns:
        The FCP time in milliseconds.
    """
    with ExitStack() as stack:
        if trace_config is None:
            trace_config = stack.enter_context(
                trace.histograms_trace_config(__FCP_HISTOGRAM_NAME)
            )

        if not os.path.exists(trace_config):
            raise FileNotFoundError(f"Trace config not found at {trace_config}")

        # If no trace file is provided, create a temporary one that will be
        # cleaned up upon exiting the context.
        if trace_file is None:
            temporary_recorded_trace = stack.enter_context(
                tempfile.NamedTemporaryFile(mode='w')
            )
            trace_file = trace.TraceFile(temporary_recorded_trace.name)

        return await _measure_fcp(app, url, trace_file, trace_config)


async def _measure_fcp(app, url, trace_file, trace_config):
    async with trace_file.record(trace_config):
        # Allow Perfetto to start recording the trace
        await asyncio.sleep(2)

        await app.start(url=url)
        await asyncio.sleep(10)

    df = await trace_file.query(
        trace.histogram_values_query(__FCP_HISTOGRAM_NAME)
    )
    try:
        return int(df.iloc[0, 0])
    except IndexError:
        raise LookupError
