import os

import numpy as np
import pytest

from kokiy.shell_2d import Shell2D

ATOL = 1e-8


# define tests
def _export_geo(datadir, tmpdir, shell, show):
    name, shell = shell

    all_str = "_all" if show else ""
    base_filename = f"{name}{all_str}.geo"

    filename = os.path.join(tmpdir, base_filename)

    shell.export_geo(filename, show_all=show)

    # created file
    with open(filename, "r") as file:
        created_txt = file.read()

    # stored file
    filename = os.path.join(datadir, "geo", base_filename)
    with open(filename, "r") as file:
        stored_txt = file.read()

    assert created_txt == stored_txt


def _replicate(shell):
    shell_2d, shell = shell

    new_shape = [3, 6]
    if not isinstance(shell, Shell2D):
        new_shape.append(3)

    new_shell = shell.replicate(new_shape)

    np.testing.assert_array_equal(new_shell.shape, new_shape)


@pytest.mark.parametrize("show_all", [False, True])
def test_export_geo(datadir, tmpdir, cartshell, show_all):
    _export_geo(datadir, tmpdir, cartshell, show_all)


@pytest.mark.parametrize("show_all", [False, True])
def test_export_geo(datadir, tmpdir, axishell, show_all):
    _export_geo(datadir, tmpdir, axishell, show_all)


@pytest.mark.parametrize("show_all", [False, True])
def test_export_geo(datadir, tmpdir, param_thickaxishell, show_all):
    _export_geo(datadir, tmpdir, param_thickaxishell, show_all)


def test_replicate_shell_2d(shell_2d):
    _replicate(shell_2d)


def test_replicate_thickshell(thickshell):
    _replicate(thickshell)


def test_mask(axishell):
    # TODO: test also on a cartshell and thickshell (backward compatibility)
    _, axishell = axishell

    point_cloud = np.array([[0.1, 0.12, 0.0]])
    tolerance = 0.04
    mask = axishell.set_mask_on_shell(point_cloud, tolerance)
    target_field = np.array(
        [
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
            [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
            [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
            [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
            [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
            [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        ]
    )
    np.testing.assert_array_equal(mask, target_field)
