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)

[((28, 22, 28, 57), 'gefest.core.structure.structure.Structure', 'Structure', ({(28, 32, 28, 56): '[unclosed_triangle_poly]'}, {}), '([unclosed_triangle_poly])', False, 'from gefest.core.structure.structure import Structure\n'), ((36, 22, 36, 49), 'gefest.core.structure.structure.Structure', 'Structure', ({(36, 32, 36, 48): '[incorrect_poly]'}, {}), '([incorrect_poly])', False, 'from gefest.core.structure.structure import Structure\n'), ((44, 22, 44, 60), 'gefest.core.structure.structure.Structure', 'Structure', ({(44, 32, 44, 59): '[out_bounds_rectangle_poly]'}, {}), '([out_bounds_rectangle_poly])', False, 'from gefest.core.structure.structure import Structure\n'), ((56, 22, 56, 74), 'gefest.core.structure.structure.Structure', 'Structure', ({(56, 32, 56, 73): '[poly_like_fixed, unclosed_triangle_poly]'}, {}), '([poly_like_fixed, unclosed_triangle_poly])', False, 'from gefest.core.structure.structure import Structure\n'), ((65, 16, 65, 48), 'copy.deepcopy', 'deepcopy', ({(65, 25, 65, 47): 'unclosed_triangle_poly'}, {}), '(unclosed_triangle_poly)', False, 'from copy import deepcopy\n'), ((67, 22, 67, 68), 'gefest.core.structure.structure.Structure', 'Structure', ({(67, 32, 67, 67): '[unclosed_triangle_poly, same_poly]'}, {}), '([unclosed_triangle_poly, same_poly])', False, 'from gefest.core.structure.structure import Structure\n'), ((16, 57, 16, 71), 'gefest.core.structure.point.Point', 'Point', ({(16, 63, 16, 70): '*coords'}, {}), '(*coords)', False, 'from gefest.core.structure.point import Point\n'), ((19, 53, 19, 67), 'gefest.core.structure.point.Point', 'Point', ({(19, 59, 19, 66): '*coords'}, {}), '(*coords)', False, 'from gefest.core.structure.point import Point\n'), ((22, 51, 22, 65), 'gefest.core.structure.point.Point', 'Point', ({(22, 57, 22, 64): '*coords'}, {}), '(*coords)', False, 'from gefest.core.structure.point import Point\n'), ((55, 52, 55, 65), 'gefest.core.structure.point.Point', 'Point', ({(55, 58, 55, 60): '15', (55, 62, 55, 64): '30'}, {}), '(15, 30)', False, 'from gefest.core.structure.point import Point\n'), ((55, 67, 55, 80), 'gefest.core.structure.point.Point', 'Point', ({(55, 73, 55, 75): '40', (55, 77, 55, 79): '30'}, {}), '(40, 30)', False, 'from gefest.core.structure.point import Point\n'), ((55, 82, 55, 95), 'gefest.core.structure.point.Point', 'Point', ({(55, 88, 55, 90): '15', (55, 92, 55, 94): '40'}, {}), '(15, 40)', False, 'from gefest.core.structure.point import Point\n')]