from collections import namedtuple
from dataclasses import dataclass
from enum import Enum
from typing import List, Optional
@dataclass
class CarInfo:
  name: str
  package: str
  video_link: Optional[str] = None
  footnotes: Optional[List[Enum]] = None
  min_steer_speed: Optional[float] = None
  min_enable_speed: Optional[float] = None
  good_torque: bool = False
  def get_stars(self, CP, non_tested_cars):
    # TODO: set all the min steer speeds in carParams and remove this
    min_steer_speed = CP.minSteerSpeed
    if self.min_steer_speed is not None:
      min_steer_speed = self.min_steer_speed
      assert CP.minSteerSpeed == 0, f"Minimum steer speed set in both CarInfo and CarParams for {CP.carFingerprint}"
    # TODO: set all the min enable speeds in carParams correctly and remove this
    min_enable_speed = CP.minEnableSpeed
    if self.min_enable_speed is not None:
      min_enable_speed = self.min_enable_speed
    stars = {
      Column.LONGITUDINAL: CP.openpilotLongitudinalControl and not CP.radarOffCan,
      Column.FSR_LONGITUDINAL: min_enable_speed <= 0.,
      Column.FSR_STEERING: min_steer_speed <= 0.,
      Column.STEERING_TORQUE: self.good_torque,
      Column.MAINTAINED: CP.carFingerprint not in non_tested_cars,
    }
    for column in StarColumns:
      stars[column] = Star.FULL if stars[column] else Star.EMPTY
      # Demote if footnote specifies a star
      footnote = get_footnote(self.footnotes, column)
      if footnote is not None and footnote.value.star is not None:
        stars[column] = footnote.value.star
    return [stars[column] for column in StarColumns]
  def get_row(self, all_footnotes, stars):
    # TODO: add YouTube vidos
    make, model = self.name.split(' ', 1)
    row = [make, model, self.package, *stars]
    # Check for car footnotes and get star icons
    for row_idx, column in enumerate(Column):
      if column in StarColumns:
        row[row_idx] = row[row_idx].icon
      footnote = get_footnote(self.footnotes, column)
      if footnote is not None:
        row[row_idx] += f"[{all_footnotes[footnote]}](#Footnotes)"
    return row
class Tier(Enum):
  GOLD = "Gold"
  SILVER = "Silver"
  BRONZE = "Bronze"
class Column(Enum):
  MAKE = "Make"
  MODEL = "Model"
  PACKAGE = "Supported Package"
  LONGITUDINAL = "openpilot ACC"
  FSR_LONGITUDINAL = "Stop and Go"
  FSR_STEERING = "Steer to 0"
  STEERING_TORQUE = "Steering Torque"
  MAINTAINED = "Actively Maintained"
class Star(Enum):
  FULL = "full"
  HALF = "half"
  EMPTY = "empty"
  @property
  def icon(self):
    return f'
'
StarColumns = list(Column)[3:]
CarFootnote = namedtuple("CarFootnote", ["text", "column", "star"], defaults=[None])
def get_footnote(footnotes: Optional[List[Enum]], column: Column) -> Optional[Enum]:
  # Returns applicable footnote given current column
  if footnotes is not None:
    for fn in footnotes:
      if fn.value.column == column:
        return fn
  return None