# © 2018 James R. Barlow: github.com/jbarlow83
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.


"""Interface to pngquant executable"""

from contextlib import contextmanager
from io import BytesIO
from pathlib import Path
from subprocess import PIPE

from PIL import Image

from ocrmypdf.exceptions import MissingDependencyError
from ocrmypdf.subprocess import get_version, run


def version():
    return get_version('pngquant', regex=r'(\d+(\.\d+)*).*')


def available():
    try:
        version()
    except MissingDependencyError:
        return False
    return True


@contextmanager
def input_as_png(input_file: Path):
    if not input_file.name.endswith('.png'):
        with Image.open(input_file) as im:
            bio = BytesIO()
            im.save(bio, format='png')
            bio.seek(0)
            yield bio
    else:
        with open(input_file, 'rb') as f:
            yield f


def quantize(input_file: Path, output_file: Path, quality_min: int, quality_max: int):
    with input_as_png(input_file) as input_stream:
        args = [
            'pngquant',
            '--force',
            '--skip-if-larger',
            '--quality',
            f'{quality_min}-{quality_max}',
            '--',  # pngquant: stop processing arguments
            '-',  # pngquant: stream input and output
        ]
        result = run(args, stdin=input_stream, stdout=PIPE, stderr=PIPE, check=False)

    if result.returncode == 0:
        # input_file could be the same as output_file, so we defer the write
        output_file.write_bytes(result.stdout)


def quantize_mp(args):
    return quantize(*args)
