import collections
from fontbakery.utils import get_name_entry_strings
from fontTools import ttLib
from lxml import etree
from pathlib import Path
import pytest
from typing import Tuple


_KNOWN_PATHLESS = {
  "NotoSansSymbols-Regular-Subsetted.ttf",
  "NotoColorEmoji.ttf",
  "NotoColorEmojiFlags.ttf",
  "NotoSansSymbols-Regular-Subsetted2.ttf",
}
_POSTSCRIPT_NAME = 6



def _repo_root() -> Path:
  root = (Path(__file__).parent / "..").absolute()
  if not (root / "LICENSE").is_file():
    raise IOError(f"{root} does not contain LICENSE")
  return root


def _noto_4_android_file() -> Path:
  xml_file = _repo_root() / "android-connection" / "noto-fonts-4-android.xml"
  if not xml_file.is_file():
    raise IOError(f"No file {xml_file}")
  return xml_file


def _font_file(font_el) -> str:
  return ("".join(font_el.itertext())).strip()


def _font_path(font_el) -> Path:
  name = _font_file(font_el)
  path = font_el.attrib["path"]
  return _repo_root() / path / name


def _is_collection(font_el) -> bool:
  return _font_file(font_el).lower().endswith(".ttc")


def _open_font(font_el) -> ttLib.TTFont:
  path = _font_path(font_el)
  if not path.is_file():
    raise IOError(f"No such file: {path}")

  if _is_collection(font_el):
    return ttLib.TTFont(str(path), fontNumber=int(font_el.attrib["index"]))
  return ttLib.TTFont(str(path))


def _open_font_path(path, fontNumber) -> ttLib.TTFont:
  if not path.is_file():
    raise IOError(f"No such file: {path}")
  if str(path).lower().endswith(".ttc"):
    return ttLib.TTFont(str(path), fontNumber=int(fontNumber))
  return ttLib.TTFont(str(path))


def _axis(font, tag):
  if "fvar" not in font:
    return None
  axes = tuple(a for a in font["fvar"].axes if a.axisTag == tag)
  if not axes:
    return None
  assert len(axes) < 2, f"only 0 or 1 fvar entries supported; {tag} has more"
  return axes[0]


def _weight(font: ttLib.TTFont) -> Tuple[int, int, int]:
  maybe_wght = _axis(font, "wght")
  if maybe_wght:
    return (maybe_wght.minValue, maybe_wght.defaultValue, maybe_wght.maxValue)
  os2_weight = font["OS/2"].usWeightClass
  return (os2_weight, os2_weight, os2_weight)


def _psname(font_el) -> str:
  # Not every font element will have postScriptName tag. If it's not present then it is assumeed
  # that it's the filename less extension
  psn = font_el.attrib.get("postScriptName", None)
  if psn:
    return psn
  path = _font_path(font_el)
  assert path.is_file(), f"{path} missing"
  return path.stem


def test_fonts_have_path():
  root = etree.parse(str(_noto_4_android_file()))
  bad = []
  for font in root.iter("font"):
    font_file = _font_file(font)
    if font_file in _KNOWN_PATHLESS:
      assert "path" not in font.attrib, f"{font_file} not expected to have path. Correct _KNOWN_PATHLESS if you just added path"
      continue

    if not font.attrib.get("path", ""):
      bad.append(font_file)
  assert not bad, "Missing path attribute: " + ", ".join(bad)


def test_ttcs_have_index():
  root = etree.parse(str(_noto_4_android_file()))
  bad = []
  for font in root.iter("font"):
    if not _is_collection(font):
      continue
    if "index" not in font.attrib:
      bad.append(_font_file(font))
  assert not bad, "Missing index attribute: " + ", ".join(bad)


def test_font_paths_are_valid():
  root = etree.parse(str(_noto_4_android_file()))
  bad = []
  for font in root.xpath("//font[@path]"):
    path = _font_path(font)
    if not path.is_file():
      bad.append(str(path))
  assert not bad, "No such file: " + ", ".join(bad)


def test_font_weights():
  root = etree.parse(str(_noto_4_android_file()))
  errors = []
  for font_el in root.xpath("//font[@path]"):
    xml_weight = int(font_el.attrib["weight"])
    path = _font_path(font_el)

    font = _open_font(font_el)
    min_wght, default_wght, max_weight = _weight(font)

    if xml_weight < min_wght or xml_weight > max_weight:
      error_str = f"{_font_file(font_el)} weight {xml_weight} outside font capability {min_wght}..{max_weight}"
      errors.append(error_str)

  assert not errors, ", ".join(errors)


def test_font_full_weight_coverage():
  root = etree.parse(str(_noto_4_android_file()))
  errors = []
  for family in root.iter("family"):
    font_to_xml_weights = collections.defaultdict(set)
    for font in family.xpath("//font[@path]"): 
      font_to_xml_weights[(_font_path(font), font.attrib.get("index", -1))].add(int(font.attrib["weight"]))

  # now you have a map of font path => set of weights in xml
  for (font_path, font_number), xml_weights in font_to_xml_weights.items():
  # open the font, compute the 100 weights between it's min/max weight
  # if xml_weights != computed weights add this to the error list
    font = _open_font_path(font_path, font_number)
    min_wght, default_wght, max_weight = _weight(font)
    if min(xml_weights) > min_wght or max(xml_weights) < max_weight:
      errors.append(f"{font_path} weight range {min(xml_weights)}..{max(xml_weights)} could be expanded to {min_wght}..{max_weight}")

  assert not errors, ", ".join(errors)


def test_font_psnames():
  root = etree.parse(str(_noto_4_android_file()))
  errors = []
  font_to_xml_psnames = collections.defaultdict(set)

  for font_el in root.xpath("//font[@path]"): 
    path = _font_path(font_el)
    psname = _psname(font_el)
    font_to_xml_psnames[(path, font_el.attrib.get("index", -1))].add(str(psname))

  for (font_path, font_number), xml_psnames in font_to_xml_psnames.items():
    font = _open_font_path(font_path, font_number)
    postscript_names = set(get_name_entry_strings(font, _POSTSCRIPT_NAME))
    if len(postscript_names) != 1:
      errors.append(f"font file {font_path} should have a single postScriptName and not {postscript_names}")
      continue
    for xml_psname in xml_psnames:
      if not (xml_psname in postscript_names):
        errors.append(f"postScriptName=\"{postscript_names[0]}\" in font file {font_path} doesn't match the entry in XML: {xml_psname}")

  assert not errors, ", ".join(errors)
