#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

import sys
from pathlib import Path
import re
from typing import Tuple
import colorsys


def invert_rgb_luma(r: float, g: float, b: float) -> Tuple[float, float, float]:
    h, l, s = colorsys.rgb_to_hls(r, g, b)
    return colorsys.hls_to_rgb(h, (1-l)**(6/10), s)


def byte2hex(byte: int) -> str:
    return ('0'*3+hex(byte)[2:])[-2:]


def invert_color_hex(text: re.Match) -> str:
    read_hex: str = text.group(1).upper()
    transparency = ''
    if len(read_hex) == 8:
        transparency = read_hex[:2]
        if transparency == 'FF':
            return f'#{read_hex.upper()}'
        read_hex = read_hex[2:]
    elif len(read_hex) != 6:
        raise ValueError()
    inverted_rgb: Tuple[int, int, int] = tuple(
        map(round, map((255.0).__mul__, invert_rgb_luma(
            int(read_hex[0:2], 16)/255,
            int(read_hex[2:4], 16)/255,
            int(read_hex[4:6], 16)/255,
        ))))
    return f'#{transparency}{byte2hex(inverted_rgb[0])}{byte2hex(inverted_rgb[1])}{byte2hex(inverted_rgb[2])}'.upper()


def do_invert_xml(source: Path, destination: Path):
    if not source.is_file():
        raise FileNotFoundError(source)
    if not destination.parent.exists():
        destination.parent.mkdir(parents=True, exist_ok=True)
    elif destination.parent.exists() and not destination.parent.is_dir():
        raise NotADirectoryError(destination.parent)
    inverted = re.sub(r'#([0-9a-fA-F]+)',
                      invert_color_hex,
                      source.read_text('utf-8'),
                      )
    print(inverted)
    destination.write_text(inverted, 'utf-8')


def main():
    if len(sys.argv) != 3:
        print(
            f'Usage:\n  {sys.argv[0]} <path/to/source/colors.xml> <path/to/destination/colors.xml>', file=sys.stderr)
    else:
        do_invert_xml(Path(sys.argv[1]), Path(sys.argv[2]))


if __name__ == '__main__':
    main()
