/*
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.microsoft.playwright;

import com.microsoft.playwright.options.*;
import java.nio.file.Path;
import java.util.regex.Pattern;

/**
 * API for collecting and saving Playwright traces. Playwright traces can be opened in <a
 * href="https://playwright.dev/java/docs/trace-viewer">Trace Viewer</a> after Playwright script runs.
 *
 * <p> <strong>NOTE:</strong> You probably want to <a href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enable tracing in
 * your config file</a> instead of using {@code context.tracing}.The {@code context.tracing} API captures browser operations and network activity, but it doesn't record test assertions
 * (like {@code expect} calls). We recommend <a
 * href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enabling tracing through Playwright Test
 * configuration</a>, which includes those assertions and provides a more complete trace for debugging test failures.
 *
 * <p> Start recording a trace before performing actions. At the end, stop tracing and save it to a file.
 * <pre>{@code
 * Browser browser = chromium.launch();
 * BrowserContext context = browser.newContext();
 * context.tracing().start(new Tracing.StartOptions()
 *   .setScreenshots(true)
 *   .setSnapshots(true));
 * Page page = context.newPage();
 * page.navigate("https://playwright.dev");
 * context.tracing().stop(new Tracing.StopOptions()
 *   .setPath(Paths.get("trace.zip")));
 * }</pre>
 */
public interface Tracing {
  class StartOptions {
    /**
     * When enabled, the trace is written to an unarchived file that is updated in real time as actions occur, instead of
     * caching changes and archiving them into a zip file at the end. This is useful for live trace viewing during test
     * execution.
     */
    public Boolean live;
    /**
     * If specified, intermediate trace files are going to be saved into the files with the given name prefix inside the {@code
     * tracesDir} directory specified in {@link com.microsoft.playwright.BrowserType#launch BrowserType.launch()}. To specify
     * the final trace zip file name, you need to pass {@code path} option to {@link com.microsoft.playwright.Tracing#stop
     * Tracing.stop()} instead.
     */
    public String name;
    /**
     * Whether to capture screenshots during tracing. Screenshots are used to build a timeline preview.
     */
    public Boolean screenshots;
    /**
     * If this option is true tracing will
     * <ul>
     * <li> capture DOM snapshot on every action</li>
     * <li> record network activity</li>
     * </ul>
     */
    public Boolean snapshots;
    /**
     * Whether to include source files for trace actions. List of the directories with source code for the application must be
     * provided via {@code PLAYWRIGHT_JAVA_SRC} environment variable (the paths should be separated by ';' on Windows and by
     * ':' on other platforms).
     */
    public Boolean sources;
    /**
     * Trace name to be shown in the Trace Viewer.
     */
    public String title;

    /**
     * When enabled, the trace is written to an unarchived file that is updated in real time as actions occur, instead of
     * caching changes and archiving them into a zip file at the end. This is useful for live trace viewing during test
     * execution.
     */
    public StartOptions setLive(boolean live) {
      this.live = live;
      return this;
    }
    /**
     * If specified, intermediate trace files are going to be saved into the files with the given name prefix inside the {@code
     * tracesDir} directory specified in {@link com.microsoft.playwright.BrowserType#launch BrowserType.launch()}. To specify
     * the final trace zip file name, you need to pass {@code path} option to {@link com.microsoft.playwright.Tracing#stop
     * Tracing.stop()} instead.
     */
    public StartOptions setName(String name) {
      this.name = name;
      return this;
    }
    /**
     * Whether to capture screenshots during tracing. Screenshots are used to build a timeline preview.
     */
    public StartOptions setScreenshots(boolean screenshots) {
      this.screenshots = screenshots;
      return this;
    }
    /**
     * If this option is true tracing will
     * <ul>
     * <li> capture DOM snapshot on every action</li>
     * <li> record network activity</li>
     * </ul>
     */
    public StartOptions setSnapshots(boolean snapshots) {
      this.snapshots = snapshots;
      return this;
    }
    /**
     * Whether to include source files for trace actions. List of the directories with source code for the application must be
     * provided via {@code PLAYWRIGHT_JAVA_SRC} environment variable (the paths should be separated by ';' on Windows and by
     * ':' on other platforms).
     */
    public StartOptions setSources(boolean sources) {
      this.sources = sources;
      return this;
    }
    /**
     * Trace name to be shown in the Trace Viewer.
     */
    public StartOptions setTitle(String title) {
      this.title = title;
      return this;
    }
  }
  class StartChunkOptions {
    /**
     * If specified, intermediate trace files are going to be saved into the files with the given name prefix inside the {@code
     * tracesDir} directory specified in {@link com.microsoft.playwright.BrowserType#launch BrowserType.launch()}. To specify
     * the final trace zip file name, you need to pass {@code path} option to {@link com.microsoft.playwright.Tracing#stopChunk
     * Tracing.stopChunk()} instead.
     */
    public String name;
    /**
     * Trace name to be shown in the Trace Viewer.
     */
    public String title;

    /**
     * If specified, intermediate trace files are going to be saved into the files with the given name prefix inside the {@code
     * tracesDir} directory specified in {@link com.microsoft.playwright.BrowserType#launch BrowserType.launch()}. To specify
     * the final trace zip file name, you need to pass {@code path} option to {@link com.microsoft.playwright.Tracing#stopChunk
     * Tracing.stopChunk()} instead.
     */
    public StartChunkOptions setName(String name) {
      this.name = name;
      return this;
    }
    /**
     * Trace name to be shown in the Trace Viewer.
     */
    public StartChunkOptions setTitle(String title) {
      this.title = title;
      return this;
    }
  }
  class StartHarOptions {
    /**
     * Optional setting to control resource content management. If {@code omit} is specified, content is not persisted. If
     * {@code attach} is specified, resources are persisted as separate files or entries in the ZIP archive. If {@code embed}
     * is specified, content is stored inline the HAR file as per HAR specification. Defaults to {@code attach} for {@code
     * .zip} output files and to {@code embed} for all other file extensions.
     */
    public HarContentPolicy content;
    /**
     * When set to {@code minimal}, only record information necessary for routing from HAR. This omits sizes, timing, page,
     * cookies, security and other types of HAR information that are not used when replaying from HAR. Defaults to {@code
     * full}.
     */
    public HarMode mode;
    /**
     * A glob or regex pattern to filter requests that are stored in the HAR. Defaults to none.
     */
    public Object urlFilter;

    /**
     * Optional setting to control resource content management. If {@code omit} is specified, content is not persisted. If
     * {@code attach} is specified, resources are persisted as separate files or entries in the ZIP archive. If {@code embed}
     * is specified, content is stored inline the HAR file as per HAR specification. Defaults to {@code attach} for {@code
     * .zip} output files and to {@code embed} for all other file extensions.
     */
    public StartHarOptions setContent(HarContentPolicy content) {
      this.content = content;
      return this;
    }
    /**
     * When set to {@code minimal}, only record information necessary for routing from HAR. This omits sizes, timing, page,
     * cookies, security and other types of HAR information that are not used when replaying from HAR. Defaults to {@code
     * full}.
     */
    public StartHarOptions setMode(HarMode mode) {
      this.mode = mode;
      return this;
    }
    /**
     * A glob or regex pattern to filter requests that are stored in the HAR. Defaults to none.
     */
    public StartHarOptions setUrlFilter(String urlFilter) {
      this.urlFilter = urlFilter;
      return this;
    }
    /**
     * A glob or regex pattern to filter requests that are stored in the HAR. Defaults to none.
     */
    public StartHarOptions setUrlFilter(Pattern urlFilter) {
      this.urlFilter = urlFilter;
      return this;
    }
  }
  class GroupOptions {
    /**
     * Specifies a custom location for the group to be shown in the trace viewer. Defaults to the location of the {@link
     * com.microsoft.playwright.Tracing#group Tracing.group()} call.
     */
    public Location location;

    /**
     * Specifies a custom location for the group to be shown in the trace viewer. Defaults to the location of the {@link
     * com.microsoft.playwright.Tracing#group Tracing.group()} call.
     */
    public GroupOptions setLocation(String file) {
      return setLocation(new Location(file));
    }
    /**
     * Specifies a custom location for the group to be shown in the trace viewer. Defaults to the location of the {@link
     * com.microsoft.playwright.Tracing#group Tracing.group()} call.
     */
    public GroupOptions setLocation(Location location) {
      this.location = location;
      return this;
    }
  }
  class StopOptions {
    /**
     * Export trace into the file with the given path.
     */
    public Path path;

    /**
     * Export trace into the file with the given path.
     */
    public StopOptions setPath(Path path) {
      this.path = path;
      return this;
    }
  }
  class StopChunkOptions {
    /**
     * Export trace collected since the last {@link com.microsoft.playwright.Tracing#startChunk Tracing.startChunk()} call into
     * the file with the given path.
     */
    public Path path;

    /**
     * Export trace collected since the last {@link com.microsoft.playwright.Tracing#startChunk Tracing.startChunk()} call into
     * the file with the given path.
     */
    public StopChunkOptions setPath(Path path) {
      this.path = path;
      return this;
    }
  }
  /**
   * Start tracing.
   *
   * <p> <strong>NOTE:</strong> You probably want to <a href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enable tracing in
   * your config file</a> instead of using {@code Tracing.start}.The {@code context.tracing} API captures browser operations and network activity, but it doesn't record test assertions
   * (like {@code expect} calls). We recommend <a
   * href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enabling tracing through Playwright Test
   * configuration</a>, which includes those assertions and provides a more complete trace for debugging test failures.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * context.tracing().start(new Tracing.StartOptions()
   *   .setScreenshots(true)
   *   .setSnapshots(true));
   * Page page = context.newPage();
   * page.navigate("https://playwright.dev");
   * context.tracing().stop(new Tracing.StopOptions()
   *   .setPath(Paths.get("trace.zip")));
   * }</pre>
   *
   * @since v1.12
   */
  default void start() {
    start(null);
  }
  /**
   * Start tracing.
   *
   * <p> <strong>NOTE:</strong> You probably want to <a href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enable tracing in
   * your config file</a> instead of using {@code Tracing.start}.The {@code context.tracing} API captures browser operations and network activity, but it doesn't record test assertions
   * (like {@code expect} calls). We recommend <a
   * href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enabling tracing through Playwright Test
   * configuration</a>, which includes those assertions and provides a more complete trace for debugging test failures.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * context.tracing().start(new Tracing.StartOptions()
   *   .setScreenshots(true)
   *   .setSnapshots(true));
   * Page page = context.newPage();
   * page.navigate("https://playwright.dev");
   * context.tracing().stop(new Tracing.StopOptions()
   *   .setPath(Paths.get("trace.zip")));
   * }</pre>
   *
   * @since v1.12
   */
  void start(StartOptions options);
  /**
   * Start a new trace chunk. If you'd like to record multiple traces on the same {@code BrowserContext}, use {@link
   * com.microsoft.playwright.Tracing#start Tracing.start()} once, and then create multiple trace chunks with {@link
   * com.microsoft.playwright.Tracing#startChunk Tracing.startChunk()} and {@link com.microsoft.playwright.Tracing#stopChunk
   * Tracing.stopChunk()}.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * context.tracing().start(new Tracing.StartOptions()
   *   .setScreenshots(true)
   *   .setSnapshots(true));
   * Page page = context.newPage();
   * page.navigate("https://playwright.dev");
   *
   * context.tracing().startChunk();
   * page.getByText("Get Started").click();
   * // Everything between startChunk and stopChunk will be recorded in the trace.
   * context.tracing().stopChunk(new Tracing.StopChunkOptions()
   *   .setPath(Paths.get("trace1.zip")));
   *
   * context.tracing().startChunk();
   * page.navigate("http://example.com");
   * // Save a second trace file with different actions.
   * context.tracing().stopChunk(new Tracing.StopChunkOptions()
   *   .setPath(Paths.get("trace2.zip")));
   * }</pre>
   *
   * @since v1.15
   */
  default void startChunk() {
    startChunk(null);
  }
  /**
   * Start a new trace chunk. If you'd like to record multiple traces on the same {@code BrowserContext}, use {@link
   * com.microsoft.playwright.Tracing#start Tracing.start()} once, and then create multiple trace chunks with {@link
   * com.microsoft.playwright.Tracing#startChunk Tracing.startChunk()} and {@link com.microsoft.playwright.Tracing#stopChunk
   * Tracing.stopChunk()}.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * context.tracing().start(new Tracing.StartOptions()
   *   .setScreenshots(true)
   *   .setSnapshots(true));
   * Page page = context.newPage();
   * page.navigate("https://playwright.dev");
   *
   * context.tracing().startChunk();
   * page.getByText("Get Started").click();
   * // Everything between startChunk and stopChunk will be recorded in the trace.
   * context.tracing().stopChunk(new Tracing.StopChunkOptions()
   *   .setPath(Paths.get("trace1.zip")));
   *
   * context.tracing().startChunk();
   * page.navigate("http://example.com");
   * // Save a second trace file with different actions.
   * context.tracing().stopChunk(new Tracing.StopChunkOptions()
   *   .setPath(Paths.get("trace2.zip")));
   * }</pre>
   *
   * @since v1.15
   */
  void startChunk(StartChunkOptions options);
  /**
   * Start recording a HAR (HTTP Archive) of network activity in this context. The HAR file is written to disk when {@link
   * com.microsoft.playwright.Tracing#stopHar Tracing.stopHar()} is called, or when the returned {@code Disposable} is
   * disposed.
   *
   * <p> Only one HAR recording can be active at a time per {@code BrowserContext}.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * context.tracing().startHar(Paths.get("trace.har"));
   * Page page = context.newPage();
   * page.navigate("https://playwright.dev");
   * context.tracing().stopHar();
   * }</pre>
   *
   * @param path Path on the filesystem to write the HAR file to. If the file name ends with {@code .zip}, the HAR is saved as a zip
   * archive with response bodies attached as separate files.
   * @since v1.60
   */
  default AutoCloseable startHar(Path path) {
    return startHar(path, null);
  }
  /**
   * Start recording a HAR (HTTP Archive) of network activity in this context. The HAR file is written to disk when {@link
   * com.microsoft.playwright.Tracing#stopHar Tracing.stopHar()} is called, or when the returned {@code Disposable} is
   * disposed.
   *
   * <p> Only one HAR recording can be active at a time per {@code BrowserContext}.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * context.tracing().startHar(Paths.get("trace.har"));
   * Page page = context.newPage();
   * page.navigate("https://playwright.dev");
   * context.tracing().stopHar();
   * }</pre>
   *
   * @param path Path on the filesystem to write the HAR file to. If the file name ends with {@code .zip}, the HAR is saved as a zip
   * archive with response bodies attached as separate files.
   * @since v1.60
   */
  AutoCloseable startHar(Path path, StartHarOptions options);
  /**
   * <strong>NOTE:</strong> Use {@code test.step} instead when available.
   *
   * <p> Creates a new group within the trace, assigning any subsequent API calls to this group, until {@link
   * com.microsoft.playwright.Tracing#groupEnd Tracing.groupEnd()} is called. Groups can be nested and will be visible in the
   * trace viewer.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * // All actions between group and groupEnd
   * // will be shown in the trace viewer as a group.
   * page.context().tracing().group("Open Playwright.dev > API");
   * page.navigate("https://playwright.dev/");
   * page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("API")).click();
   * page.context().tracing().groupEnd();
   * }</pre>
   *
   * @param name Group name shown in the trace viewer.
   * @since v1.49
   */
  default AutoCloseable group(String name) {
    return group(name, null);
  }
  /**
   * <strong>NOTE:</strong> Use {@code test.step} instead when available.
   *
   * <p> Creates a new group within the trace, assigning any subsequent API calls to this group, until {@link
   * com.microsoft.playwright.Tracing#groupEnd Tracing.groupEnd()} is called. Groups can be nested and will be visible in the
   * trace viewer.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * // All actions between group and groupEnd
   * // will be shown in the trace viewer as a group.
   * page.context().tracing().group("Open Playwright.dev > API");
   * page.navigate("https://playwright.dev/");
   * page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("API")).click();
   * page.context().tracing().groupEnd();
   * }</pre>
   *
   * @param name Group name shown in the trace viewer.
   * @since v1.49
   */
  AutoCloseable group(String name, GroupOptions options);
  /**
   * Closes the last group created by {@link com.microsoft.playwright.Tracing#group Tracing.group()}.
   *
   * @since v1.49
   */
  void groupEnd();
  /**
   * Stop tracing.
   *
   * @since v1.12
   */
  default void stop() {
    stop(null);
  }
  /**
   * Stop tracing.
   *
   * @since v1.12
   */
  void stop(StopOptions options);
  /**
   * Stop the trace chunk. See {@link com.microsoft.playwright.Tracing#startChunk Tracing.startChunk()} for more details
   * about multiple trace chunks.
   *
   * @since v1.15
   */
  default void stopChunk() {
    stopChunk(null);
  }
  /**
   * Stop the trace chunk. See {@link com.microsoft.playwright.Tracing#startChunk Tracing.startChunk()} for more details
   * about multiple trace chunks.
   *
   * @since v1.15
   */
  void stopChunk(StopChunkOptions options);
  /**
   * Stop HAR recording and save the HAR file to the path given to {@link com.microsoft.playwright.Tracing#startHar
   * Tracing.startHar()}.
   *
   * @since v1.60
   */
  void stopHar();
}

