import pytest
from calculate.utils.images import ImageMagick, ImageMagickError
import os
from calculate.utils.files import Process

@pytest.mark.images_utils
def test_imagemagick_initialization():
    im = ImageMagick()
    assert im.available
    assert not im.chroot
    
    im = ImageMagick(prefix='/mnt/somepath')
    assert not im.available
    assert im.chroot


@pytest.mark.images_utils
@pytest.mark.parametrize('case',
    [
        {
            "name": "simple path",
            "chroot": "/mnt/install",
            "source": "/mnt/install/usr/share/pixmap/image.jpg",
            "result": "/usr/share/pixmap/image.jpg",
        },
        {
            "name": "relative",
            "chroot": "/mnt/install",
            "source": "/mnt/install/usr/share/../pixmap/image.jpg",
            "result": "/usr/pixmap/image.jpg",
        },
        {
            "name": "first level",
            "chroot": "/mnt/install",
            "source": "/mnt/install/image.jpg",
            "result": "/image.jpg",
        },
        {
            "name": "Wrong",
            "chroot": "/mnt/install",
            "source": "/mnt/image.jpg",
            "result": None,
        },
    ],
    ids=lambda x:x["name"])
def test_imagemagick_trim_prefix_path(case):
    im = ImageMagick(case['chroot'])
    assert im.trim_prefix_path(case["source"]) == case["result"]

@pytest.mark.images_utils
@pytest.mark.parametrize('case',
    [
        {
            "name": "PNG file",
            "image": "tests/utils/testfiles/file.png",
            "result": (48,48),
        },
        {
            "name": "JPEG file",
            "image": "tests/utils/testfiles/file.jpg",
            "result": (320,180),
        },
        {
            "name": "No file",
            "image": "tests/utils/testfiles/file2.jpg",
            "result": None,
        },
        {
            "name": "Wrong file",
            "image": "tests/utils/testfiles/wrong.jpg",
            "result": None,
        },
    ],
    ids=lambda x:x["name"])
def test_imagemagick_get_resolutions(case):
    im = ImageMagick()
    assert im.get_image_resolution(case["image"]) == case["result"]

@pytest.fixture
def chroot_test():
    chrootpath = "/mnt/testchroot"
    assert os.getuid() == 0, "Need superuser privileges"
    if os.path.exists(chrootpath):
        os.unlink(chrootpath)
    os.symlink("/", chrootpath)
    try:
        yield chrootpath
    finally:
        os.unlink(chrootpath)

@pytest.mark.chroot
@pytest.mark.images_utils
def test_chroot_imagemagick_get_resolution(chroot_test):
    im = ImageMagick(chroot_test)
    curpath = os.getcwd()
    image_path = os.path.join(curpath, "tests/utils/testfiles/file.png")
    assert im.get_image_resolution(image_path) == (48,48)

def get_histogram(image, remap_image):
    p = Process("/usr/bin/convert", image, "-remap", remap_image, "-format", "%c", "histogram:info:-")
    return p.read()

def get_verbose_image_info(image):
    p = Process("/usr/bin/identify", "-verbose", image)
    return p.read()

@pytest.mark.images_utils
@pytest.mark.parametrize('case',
    [
        {
            # проверка, пропорционального уменьшения
            "name": "Origin test",
            "resize": (16,32),
            "result": """192: (0,0,0) #000000 black
                      64: (0,255,0) #00FF00 lime
                      256: (255,255,255) #FFFFFF white"""
        },
        {
            # проверка, что при изменении размера только по горизонтали
            # удаляются только части изображения справа и слева
            # в исходном изображении на этих частях находится белый фон
            "name": "Shrink horizontal",
            "resize": (16,16),
            "result": """192: (0,0,0) #000000 black
                      64: (0,255,0) #00FF00 lime"""
        },
        {
            # проверка, что при уменьшении изображения первоначально оно сдавливается
            # по вертикали а затем обрезаются части слева и справа
            "name": "Shrink all",
            "resize": (8,8),
            "result": """48: (0,0,0) #000000 black
                      16: (0,255,0) #00FF00 lime"""
        },
        {
            # проверка, пропорционального уменьшения
            "name": "Shrink proportionately",
            "resize": (8,16),
            "result": """48: (0,0,0) #000000 black
                      16: (0,255,0) #00FF00 lime
                      64: (255,255,255) #FFFFFF white"""
        },
        {
            # проверка, пропорционального увеличения
            "name": "Increase size proportionately",
            "resize": (32,64),
            "result": """768: (0,0,0) #000000 black
                      256: (0,255,0) #00FF00 lime
                      1024: (255,255,255) #FFFFFF white"""
        },
        {
            # проверка увеличения и обрезки по горизонтали
            "name": "Increase size and cut",
            "resize": (32,32),
            "result": """768: (0,0,0) #000000 black
                      256: (0,255,0) #00FF00 lime"""
        },
        {
            # проверка увеличения по горизонтали
            # в этом случае будет отрезан верх и низ
            # поэтому на выходе нет зелёного цвета
            "name": "Increase horizontal size",
            "resize": (16,48),
            "result": """384: (0,0,0) #000000 gray(0)
                      384: (255,255,255) #FFFFFF gray(255)"""
        },
    ],
    ids=lambda x:x["name"])
def test_imagemagick_convert(case):
    image_path = "tests/utils/testfiles/origin.png"
    output_file = "tests/utils/testfiles/test_output5.png"
    if os.path.exists(output_file):
        os.unlink(output_file)
    im = ImageMagick()
    im.default_opts = ["-filter","box"]
    assert im.convert_resize_crop_center(image_path, output_file, *case["resize"])
    histogram = get_histogram(output_file, image_path)
    discard_space = lambda x: x.replace(" ","").replace("\n","")
    assert discard_space(histogram) == discard_space(case["result"])

@pytest.mark.chroot
@pytest.mark.images_utils
def test_chroot_imagemagick_convert_center(chroot_test):
    curpath = os.getcwd()
    image_path = "tests/utils/testfiles/origin.png"
    output_file = "tests/utils/testfiles/test_output.png"
    image_path = os.path.join(curpath, image_path)
    output_file = os.path.join(curpath, output_file)
    result = """48: (0,0,0) #000000 black
                      16: (0,255,0) #00FF00 lime"""
    if os.path.exists(output_file):
        os.unlink(output_file)
    im = ImageMagick(chroot_test)
    im.default_opts = ["-filter","box"]
    assert im.convert_resize_crop_center(image_path, output_file, 8, 8)
    histogram = get_histogram(output_file, image_path)
    discard_space = lambda x: x.replace(" ","").replace("\n","")
    assert discard_space(histogram) == discard_space(result)

@pytest.mark.images_utils
def test_imagemagick_convert_gfxboot():
    output_file = "tests/utils/testfiles/test_output.jpg"
    image_path = "tests/utils/testfiles/origin.png"
    im = ImageMagick()
    im.convert_resize_gfxboot(image_path, output_file, 32, 32)
    assert "sampling-factor: 2x2" in get_verbose_image_info(output_file)

@pytest.mark.images_utils
def test_clear_imagemagick_convert():
    for output_file in (
            "tests/utils/testfiles/test_output.png",
            "tests/utils/testfiles/test_output.jpg"
        ):
        if os.path.exists(output_file):
            os.unlink(output_file)
