import pytest
from copy import deepcopy
from gefest.core.structure.point import Point
from gefest.core.structure.polygon import Polygon
from gefest.core.structure.structure import Structure
from gefest.core.algs.postproc.resolve_errors import *
from gefest.core.algs.geom.validation import *


# marking length and width for testing polygon
poly_width = 10
poly_length = 20

# creating a testing polygons via corner points
rectangle_points = [(-1, 40), (-1, poly_length+40), (-poly_width-10, poly_length+40), (-poly_width-10, 40)]
out_bounds_rectangle_poly = Polygon('rectangle', points=[Point(*coords) for coords in rectangle_points])

triangle_points = [(1, 1), (poly_width, poly_length), (1, poly_length)]
unclosed_triangle_poly = Polygon('triangle', points=[Point(*coords) for coords in triangle_points])

incorrect_points = [(5, 5), (5, poly_length), (8, poly_length), (5, 5), (5, 30)]
incorrect_poly = Polygon('incorrect_poly', points=[Point(*coords) for coords in incorrect_points])

domain = Domain()


def test_unclosed_poly():
    input_structure = Structure([unclosed_triangle_poly])
    observed_structure = postprocess(input_structure, domain)

    assert unclosed_poly(input_structure, domain)
    assert not unclosed_poly(observed_structure, domain)


def test_self_intersection():
    input_structure = Structure([incorrect_poly])
    observed_structure = postprocess(input_structure, domain)

    assert self_intersection(input_structure)
    assert not self_intersection(observed_structure)


def test_out_of_bound():
    input_structure = Structure([out_bounds_rectangle_poly])
    observed_structure = postprocess(input_structure, domain)

    assert out_of_bound(input_structure, domain)
    assert not out_of_bound(observed_structure, domain)


def test_fixed_polys():
    domain = Domain(fixed_points=[[[15, 30],
                                  [40, 30],
                                  [15, 40]]])
    poly_like_fixed = Polygon('like_fixed', points=[Point(15, 30), Point(40, 30), Point(15, 40)])
    input_structure = Structure([poly_like_fixed, unclosed_triangle_poly])
    observed_structure = postprocess(input_structure, domain)

    assert all([np.isclose(len(observed_structure.polygons), 2),
                'like_fixed' not in [poly.id for poly in observed_structure.polygons],
                'fixed' in [poly.id for poly in observed_structure.polygons]])


def test_too_close():
    same_poly = deepcopy(unclosed_triangle_poly)
    same_poly.id = 'same_triangle'
    input_structure = Structure([unclosed_triangle_poly, same_poly])
    observed_structure = postprocess(input_structure, domain)

    print(observed_structure.polygons)

    assert np.isclose(len(observed_structure.polygons), 1)

[((1059, 1094), 'gefest.core.structure.structure.Structure', 'Structure', (['[unclosed_triangle_poly]'], {}), '([unclosed_triangle_poly])\n', (1068, 1094), False, 'from gefest.core.structure.structure import Structure\n'), ((1319, 1346), 'gefest.core.structure.structure.Structure', 'Structure', (['[incorrect_poly]'], {}), '([incorrect_poly])\n', (1328, 1346), False, 'from gefest.core.structure.structure import Structure\n'), ((1558, 1596), 'gefest.core.structure.structure.Structure', 'Structure', (['[out_bounds_rectangle_poly]'], {}), '([out_bounds_rectangle_poly])\n', (1567, 1596), False, 'from gefest.core.structure.structure import Structure\n'), ((2046, 2098), 'gefest.core.structure.structure.Structure', 'Structure', (['[poly_like_fixed, unclosed_triangle_poly]'], {}), '([poly_like_fixed, unclosed_triangle_poly])\n', (2055, 2098), False, 'from gefest.core.structure.structure import Structure\n'), ((2433, 2465), 'copy.deepcopy', 'deepcopy', (['unclosed_triangle_poly'], {}), '(unclosed_triangle_poly)\n', (2441, 2465), False, 'from copy import deepcopy\n'), ((2523, 2569), 'gefest.core.structure.structure.Structure', 'Structure', (['[unclosed_triangle_poly, same_poly]'], {}), '([unclosed_triangle_poly, same_poly])\n', (2532, 2569), False, 'from gefest.core.structure.structure import Structure\n'), ((588, 602), 'gefest.core.structure.point.Point', 'Point', (['*coords'], {}), '(*coords)\n', (593, 602), False, 'from gefest.core.structure.point import Point\n'), ((762, 776), 'gefest.core.structure.point.Point', 'Point', (['*coords'], {}), '(*coords)\n', (767, 776), False, 'from gefest.core.structure.point import Point\n'), ((942, 956), 'gefest.core.structure.point.Point', 'Point', (['*coords'], {}), '(*coords)\n', (947, 956), False, 'from gefest.core.structure.point import Point\n'), ((1978, 1991), 'gefest.core.structure.point.Point', 'Point', (['(15)', '(30)'], {}), '(15, 30)\n', (1983, 1991), False, 'from gefest.core.structure.point import Point\n'), ((1993, 2006), 'gefest.core.structure.point.Point', 'Point', (['(40)', '(30)'], {}), '(40, 30)\n', (1998, 2006), False, 'from gefest.core.structure.point import Point\n'), ((2008, 2021), 'gefest.core.structure.point.Point', 'Point', (['(15)', '(40)'], {}), '(15, 40)\n', (2013, 2021), False, 'from gefest.core.structure.point import Point\n')]