from fontbakery.checkrunner import Section
from fontbakery.fonts_profile import profile_factory


def check_filter(item_type, item_id, item):
  # Filter out external tool checks for testing purposes.
  if item_type == "check" and item_id in (
      "com.google.fonts/check/ftxvalidator",
      "com.google.fonts/check/ots",
      "com.google.fonts/check/fontvalidator",
      "com.google.fonts/check/fontforge_stderr",
      "com.google.fonts/check/fontforge",
  ):
    return False

  return True


def test_external_profile():
  """Test the creation of external profiles."""
  profile = profile_factory(default_section=Section("Dalton Maag OpenType"))
  profile.auto_register(
      globals(),
      profile_imports=["fontbakery.profiles.opentype"],
      filter_func=check_filter)

  # Probe some tests
  expected_tests = ["com.google.fonts/check/family/panose_proportion",
                    "com.google.fonts/check/varfont/regular_opsz_coord"]
  profile.test_expected_checks(expected_tests)

  # Probe tests we don't want
  assert "com.google.fonts/check/ftxvalidator" not in profile._check_registry.keys()

  assert len(profile.sections) > 1

def test_profile_imports():
  """
    When a names array in profile_imports contained sub module names, the import
    would fail.

    https://github.com/googlefonts/fontbakery/issues/1886
  """
  def _test(profile_imports, expected_tests,expected_conditions=tuple()):
    profile = profile_factory(default_section=Section("Testing"))
    profile.auto_register({}, profile_imports=profile_imports)
    profile.test_expected_checks(expected_tests)
    if expected_conditions:
      registered_conditions = profile.conditions.keys()
      for name in expected_conditions:
        assert name in registered_conditions, ('"{}" is expected to be '
                                  'registered as a condition.'.format(name))

  # this is in docs/writing profiles
  profile_imports = [
    ['fontbakery.profiles', ['cmap', 'head']]
  ]
  # Probe some tests
  expected_tests = [
      "com.google.fonts/check/all_glyphs_have_codepoints", # in cmap
      "com.google.fonts/check/unitsperem"  # in head
  ]
  _test(profile_imports, expected_tests)


  # the example from issue #1886
  profile_imports = (
    (
        "fontbakery.profiles",
        (
            "cmap",
            "head",
            "os2",
            "post",
            "name",
            "hhea",
            "dsig",
            "hmtx",
            "gpos",
            "kern",
            "glyf",
            "fvar",
            "shared_conditions",
        ),
    ),
  )
  # Probe some tests
  expected_tests = [
      "com.google.fonts/check/all_glyphs_have_codepoints", # in cmap
      "com.google.fonts/check/unitsperem"  # in head
  ]
  _test(profile_imports, expected_tests)


  # make sure the suggested workaround still works:
  # https://github.com/googlefonts/fontbakery/issues/1886#issuecomment-392535435
  profile_imports = (
      "fontbakery.profiles.cmap",
      "fontbakery.profiles.head",
      "fontbakery.profiles.os2",
      "fontbakery.profiles.post",
      "fontbakery.profiles.name",
      "fontbakery.profiles.hhea",
      "fontbakery.profiles.dsig",
      "fontbakery.profiles.hmtx",
      "fontbakery.profiles.gpos",
      "fontbakery.profiles.kern",
      "fontbakery.profiles.glyf",
      "fontbakery.profiles.fvar",
      "fontbakery.profiles.shared_conditions"
  )
  # Probe some tests
  expected_tests = [
      "com.google.fonts/check/all_glyphs_have_codepoints", # in cmap
      "com.google.fonts/check/unitsperem"  # in head
  ]
  _test(profile_imports, expected_tests)


  # cherry pick attributes from a module (instead of getting submodules)
  # also from this is in docs/writing profiles
  # Import just certain attributes from modules.
  # Also, using absolute import module names:
  profile_imports = [
      # like we do in fontbakery.profiles.fvar
      ('fontbakery.profiles.shared_conditions', ('is_variable_font',
              'regular_wght_coord', 'regular_wdth_coord', 'regular_slnt_coord',
              'regular_ital_coord', 'regular_opsz_coord', 'bold_wght_coord')),
      # just as an example: import a check and a dependency/condition of
      # that check from the googlefonts specific profile:
      ('fontbakery.profiles.googlefonts', (
          # "License URL matches License text on name table?"
          'com_google_fonts_check_name_license_url',
          # This condition is a dependency of the check above:
          'familyname',
      ))
  ]
  # Probe some tests
  expected_tests = [
      "com.google.fonts/check/name/license_url"  # in googlefonts
  ]
  expected_conditions = ('is_variable_font', 'regular_wght_coord',
        'regular_wdth_coord', 'regular_slnt_coord', 'regular_ital_coord',
        'regular_opsz_coord', 'bold_wght_coord', 'familyname')
  _test(profile_imports, expected_tests, expected_conditions)


def test_opentype_checks_load():
  profile_imports = ("fontbakery.profiles.opentype", )
  profile = profile_factory(default_section=Section("OpenType Testing"))
  profile.auto_register({}, profile_imports=profile_imports)
  profile.test_dependencies()


def test_googlefonts_checks_load():
  profile_imports = ("fontbakery.profiles.googlefonts", )
  profile = profile_factory(default_section=Section("Google Fonts Testing"))
  profile.auto_register({}, profile_imports=profile_imports)
  profile.test_dependencies()


def test_in_and_exclude_checks():
  profile_imports = ("fontbakery.profiles.opentype", )
  profile = profile_factory(default_section=Section("OpenType Testing"))
  profile.auto_register({}, profile_imports=profile_imports)
  profile.test_dependencies()
  explicit_checks = ["06", "07"]  # "06" or "07" in check ID
  exclude_checks = ["065", "079"]  # "065" or "079" in check ID
  iterargs = {"font": 1}
  check_names = {
      c[1].id for c in profile.execution_order(
          iterargs,
          explicit_checks=explicit_checks,
          exclude_checks=exclude_checks)
  }
  check_names_expected = set()
  for section in profile.sections:
    for check in section.checks:
      if any(i in check.id for i in explicit_checks) and not any(
          x in check.id for x in exclude_checks):
        check_names_expected.add(check.id)
  assert check_names == check_names_expected


def test_in_and_exclude_checks_default():
  profile_imports = ("fontbakery.profiles.opentype",)
  profile = profile_factory(default_section=Section("OpenType Testing"))
  profile.auto_register({}, profile_imports=profile_imports)
  profile.test_dependencies()
  explicit_checks = None  # "All checks aboard"
  exclude_checks = None  # "No checks left behind"
  iterargs = {"font": 1}
  check_names = {
      c[1].id for c in profile.execution_order(
          iterargs,
          explicit_checks=explicit_checks,
          exclude_checks=exclude_checks)
  }
  check_names_expected = set()
  for section in profile.sections:
    for check in section.checks:
      check_names_expected.add(check.id)
  assert check_names == check_names_expected
