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

from __future__ import annotations

import abc
import dataclasses
from typing import Iterator

from typing_extensions import override

from crossbench.config import ConfigObject
from crossbench.parse import NumberParser


class TabController(ConfigObject):
  @classmethod
  @override
  def parse_str(cls, value: str) -> TabController:
    if not value or value == "single":
      return cls.single()
    if value in ("inf", "infinity"):
      return cls.forever()
    loops = NumberParser.positive_int(value, "Repeat-count")
    return cls.repeat(loops)

  @classmethod
  def default(cls) -> TabController:
    return cls.single()

  @classmethod
  def single(cls) -> TabController:
    return SingleTabController()

  @classmethod
  def multiple(cls) -> TabController:
    return RepeatTabController(1)

  @classmethod
  def repeat(cls, count: int) -> RepeatTabController:
    return RepeatTabController(count)

  @classmethod
  def forever(cls) -> TabController:
    return ForeverTabController()

  @abc.abstractmethod
  def __iter__(self) -> Iterator[None]:
    pass

  @property
  def multiple_tabs(self) -> bool:
    return True



@dataclasses.dataclass(frozen=True)
class SingleTabController(TabController):
  """
  Open given urls in one tab sequentially.
  """
  def __iter__(self) -> Iterator[None]:
    yield None

  @property
  @override
  def multiple_tabs(self) -> bool:
    return False


@dataclasses.dataclass(frozen=True)
class ForeverTabController(TabController):
  """
  Open given urls in separate tabs and repeat infinitely until
  one of the tabs gets discarded.

  Example 1: if url='cnn', it keeps opening new tabs loading cnn.

  Example 2: if urls='amazon,cnn', it keeps opening
  amazon,cnn,amazon,cnn,amazon,cnn,.... ....
  """

  def __iter__(self) -> Iterator[None]:
    while True:
      yield None


@dataclasses.dataclass(frozen=True)
class RepeatTabController(TabController):
  """
  Open given urls in separate tabs and repeat for `count` times.

  Example 1: if url='cnn', count=3, it will open 3 tabs: cnn,cnn,cnn.

  Example 2: if urls='amazon,cnn', count=3, it will open 6 tabs:
  amazon,cnn,amazon,cnn,amazon,cnn
  """
  count: int

  def __iter__(self) -> Iterator[None]:
    for _ in range(self.count):
      yield None
