#!/usr/bin/env python3

import logging
from multiprocessing import cpu_count
from multiprocessing.pool import Pool
from subprocess import check_output, run
from pathlib import Path
from itertools import chain
from typing import Final

def is_oxipng_installed():
    try:
        # Run 'oxipng --version' to check if installed
        run(["oxipng", "--version"], check=True)
        return True
    except FileNotFoundError:
        # Command not found, oxipng is not installed
        return False

try:
	import PIL
	from PIL import Image
except ImportError:
	logging.critical("Please install the python PIL library.")
	logging.critical("e.g.: python3 -m pip install PIL")
	exit()

sizes = {
	'horizontal': (
		(5120, 2880), (3840, 2160), (3200, 2000), (3200, 1800),
		(2560, 1600), (2560, 1440), (1920, 1200), (1920, 1080),
		(1680, 1050), (1600, 1200), (1440, 900), (1366, 768),
		(1280, 1024), (1280, 800), (1024, 768), (440, 247)
		),
	'vertical': ((720, 1440), (360, 720), (1080, 1920))
	}

templates = {
	'horizontal': ('base_size.png', 'base_size.jpg'),
	'vertical':  ('vertical_base_size.png', 'vertical_base_size.jpg')
	}

PIL_VERSION: Final = tuple(map(int, PIL.__version__.split(".")))


def resize_and_save_image(file: Path, image: Image, width: int, height: int) -> None:
	"""
	Image.LANCZOS is deprecated since 9.1.0 https://pillow.readthedocs.io/en/stable/deprecations.html#constants
	"""
	logging.info(f'Generating {width}x{height}')

	base_dir, extension = file.parent, file.suffix
	base_width, base_height = image.size

	if width / height > base_width / base_height:
		crop = int(base_height - height / (width / base_width)) // 2
		box = (0, crop, base_width, base_height - crop)
	elif width / height < base_width / base_height:
		crop = int(base_width - width / (height / base_height)) // 2
		box = (crop, 0, base_width - crop, base_height)
	else:
		box = None

	if PIL_VERSION >= (9, 1):
		resized_image = image.resize((width, height), Image.Resampling.LANCZOS, box)
	else:
		resized_image = image.resize((width, height), Image.LANCZOS, box)

	if extension.lower() ==  ".png":
		target = base_dir / f'{width}x{height}{extension}'
		resized_image.save(target, compress_level=0)
		run(["oxipng", str(base_dir / f'{width}x{height}{extension}')])
	else:
		resized_image.save(base_dir / f'{width}x{height}{extension}',
						quality=90, optimize=True, subsampling=1)

argument_list: list[tuple] = []

for orientation in ('horizontal', 'vertical'):
	for file in chain(*map(Path().rglob, templates[orientation])):
		image = Image.open(file)
		image.load()
		for width, height in sizes[orientation]:
			argument_list.append((file, image, width, height))
		if file.suffix.lower() == ".png" and not is_oxipng_installed():
			logging.critical("Please install 'oxipng', which is required to compress the png images.")
			exit()

with Pool(processes=cpu_count()) as pool:
	pool.starmap(resize_and_save_image, argument_list)
