from typing import Tuple

from hypothesis import given

from shewchuk import (kind,
                      vectors_dot_product)
from tests.utils import (exact_kind,
                         to_sign)
from . import strategies


@given(strategies.floats_sextuplets)
def test_basic(sextuplet: Tuple[float, float, float, float, float, float]
               ) -> None:
    (vertex_x, vertex_y, first_ray_second_ray_point_x,
     first_ray_second_ray_point_y, second_ray_point_x,
     second_ray_point_y) = sextuplet

    result = kind(vertex_x, vertex_y, first_ray_second_ray_point_x,
                  first_ray_second_ray_point_y, second_ray_point_x,
                  second_ray_point_y)

    assert isinstance(result, int)
    assert result in (-1, 0, 1)


@given(strategies.floats_quadruplets)
def test_endpoints(quadruplet: Tuple[float, float, float, float]) -> None:
    (vertex_x, vertex_y, first_ray_second_ray_point_x,
     first_ray_second_ray_point_y) = quadruplet

    assert not kind(vertex_x, vertex_y, first_ray_second_ray_point_x,
                    first_ray_second_ray_point_y, vertex_x, vertex_y)
    assert (kind(vertex_x, vertex_y, first_ray_second_ray_point_x,
                 first_ray_second_ray_point_y, first_ray_second_ray_point_x,
                 first_ray_second_ray_point_y)
            == (vertex_x != first_ray_second_ray_point_x
                or vertex_y != first_ray_second_ray_point_y))


@given(strategies.floats_sextuplets)
def test_endpoints_permutation(sextuplet: Tuple[float, float, float, float,
                                                float, float]) -> None:
    (vertex_x, vertex_y, first_ray_second_ray_point_x,
     first_ray_second_ray_point_y, second_ray_point_x,
     second_ray_point_y) = sextuplet

    result = kind(vertex_x, vertex_y, first_ray_second_ray_point_x,
                  first_ray_second_ray_point_y, second_ray_point_x,
                  second_ray_point_y)

    assert result == kind(vertex_x, vertex_y, second_ray_point_x,
                          second_ray_point_y, first_ray_second_ray_point_x,
                          first_ray_second_ray_point_y)


@given(strategies.floats_sextuplets)
def test_alternatives(sextuplet: Tuple[float, float, float, float, float,
                                       float]) -> None:
    (vertex_x, vertex_y, first_ray_second_ray_point_x,
     first_ray_second_ray_point_y, second_ray_point_x,
     second_ray_point_y) = sextuplet

    result = kind(vertex_x, vertex_y, first_ray_second_ray_point_x,
                  first_ray_second_ray_point_y, second_ray_point_x,
                  second_ray_point_y)

    assert result == to_sign(vectors_dot_product(
            vertex_x, vertex_y, first_ray_second_ray_point_x,
            first_ray_second_ray_point_y, vertex_x, vertex_y,
            second_ray_point_x, second_ray_point_y))
    assert result == exact_kind(vertex_x, vertex_y,
                                first_ray_second_ray_point_x,
                                first_ray_second_ray_point_y,
                                second_ray_point_x, second_ray_point_y)
