import logging
from pathlib import Path
from subprocess import run
import contextlib
import os
from typing import List, Optional, Tuple
from fontTools.ttLib import TTFont

import pytest

from fontTools.feaLib.builder import addOpenTypeFeaturesFromString
from fontTools.fontBuilder import FontBuilder

from fontTools.ttLib.tables.otBase import OTTableWriter, ValueRecord


def test_main(tmpdir: Path):
    """Check that calling the main function on an input TTF works."""
    glyphs = ".notdef space A Aacute B D".split()
    features = """
    @A = [A Aacute];
    @B = [B D];
    feature kern {
        pos @A @B -50;
    } kern;
    """
    fb = FontBuilder(1000)
    fb.setupGlyphOrder(glyphs)
    addOpenTypeFeaturesFromString(fb.font, features)
    input = tmpdir / "in.ttf"
    fb.save(str(input))
    output = tmpdir / "out.ttf"
    run(
        [
            "fonttools",
            "otlLib.optimize",
            "--gpos-compact-mode",
            "5",
            str(input),
            "-o",
            str(output),
        ],
        check=True,
    )
    assert output.exists()


# Copy-pasted from https://stackoverflow.com/questions/2059482/python-temporarily-modify-the-current-processs-environment
# TODO: remove when moving to the Config class
@contextlib.contextmanager
def set_env(**environ):
    """
    Temporarily set the process environment variables.

    >>> with set_env(PLUGINS_DIR=u'test/plugins'):
    ...   "PLUGINS_DIR" in os.environ
    True

    >>> "PLUGINS_DIR" in os.environ
    False

    :type environ: dict[str, unicode]
    :param environ: Environment variables to set
    """
    old_environ = dict(os.environ)
    os.environ.update(environ)
    try:
        yield
    finally:
        os.environ.clear()
        os.environ.update(old_environ)


def count_pairpos_subtables(font: TTFont) -> int:
    subtables = 0
    for lookup in font["GPOS"].table.LookupList.Lookup:
        if lookup.LookupType == 2:
            subtables += len(lookup.SubTable)
        elif lookup.LookupType == 9:
            for subtable in lookup.SubTable:
                if subtable.ExtensionLookupType == 2:
                    subtables += 1
    return subtables


def count_pairpos_bytes(font: TTFont) -> int:
    bytes = 0
    gpos = font["GPOS"]
    for lookup in font["GPOS"].table.LookupList.Lookup:
        if lookup.LookupType == 2:
            w = OTTableWriter(tableTag=gpos.tableTag)
            lookup.compile(w, font)
            bytes += len(w.getAllData())
        elif lookup.LookupType == 9:
            if any(subtable.ExtensionLookupType == 2 for subtable in lookup.SubTable):
                w = OTTableWriter(tableTag=gpos.tableTag)
                lookup.compile(w, font)
                bytes += len(w.getAllData())
    return bytes


def get_kerning_by_blocks(blocks: List[Tuple[int, int]]) -> Tuple[List[str], str]:
    """Generate a highly compressible font by generating a bunch of rectangular
    blocks on the diagonal that can easily be sliced into subtables.

    Returns the list of glyphs and feature code of the font.
    """
    value = 0
    glyphs: List[str] = []
    rules = []
    # Each block is like a script in a multi-script font
    for script, (width, height) in enumerate(blocks):
        glyphs.extend(f"g_{script}_{i}" for i in range(max(width, height)))
        for l in range(height):
            for r in range(width):
                value += 1
                rules.append((f"g_{script}_{l}", f"g_{script}_{r}", value))
    classes = "\n".join([f"@{g} = [{g}];" for g in glyphs])
    statements = "\n".join([f"pos @{l} @{r} {v};" for (l, r, v) in rules])
    features = f"""
        {classes}
        feature kern {{
            {statements}
        }} kern;
    """
    return glyphs, features


@pytest.mark.parametrize(
    ("blocks", "mode", "expected_subtables", "expected_bytes"),
    [
        # Mode = 0 = no optimization leads to 650 bytes of GPOS
        ([(15, 3), (2, 10)], None, 1, 602),
        # Optimization level 1 recognizes the 2 blocks and splits into 2
        # subtables = adds 1 subtable leading to a size reduction of
        # (602-298)/602 = 50%
        ([(15, 3), (2, 10)], 1, 2, 298),
        # On a bigger block configuration, we see that mode=5 doesn't create
        # as many subtables as it could, because of the stop criteria
        ([(4, 4) for _ in range(20)], 5, 14, 2042),
        # while level=9 creates as many subtables as there were blocks on the
        # diagonal and yields a better saving
        ([(4, 4) for _ in range(20)], 9, 20, 1886),
        # On a fully occupied kerning matrix, even the strategy 9 doesn't
        # split anything.
        ([(10, 10)], 9, 1, 304)
    ],
)
def test_optimization_mode(
    caplog,
    blocks: List[Tuple[int, int]],
    mode: Optional[int],
    expected_subtables: int,
    expected_bytes: int,
):
    """Check that the optimizations are off by default, and that increasing
    the optimization level creates more subtables and a smaller byte size.
    """
    caplog.set_level(logging.DEBUG)

    glyphs, features = get_kerning_by_blocks(blocks)
    glyphs = [".notdef space"] + glyphs

    env = {}
    if mode is not None:
        # NOTE: activating this optimization via the environment variable is
        # experimental and may not be supported once an alternative mechanism
        # is in place. See: https://github.com/fonttools/fonttools/issues/2349
        env["FONTTOOLS_GPOS_COMPACT_MODE"] = str(mode)
    with set_env(**env):
        fb = FontBuilder(1000)
        fb.setupGlyphOrder(glyphs)
        addOpenTypeFeaturesFromString(fb.font, features)
        assert expected_subtables == count_pairpos_subtables(fb.font)
        assert expected_bytes == count_pairpos_bytes(fb.font)
