package complex;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.within;
import static org.junit.jupiter.api.Assertions.fail;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.sql.SQLOutput;


/**
 * Test class for the complex class.
 */

class ComplexTest {
  private Complex z;
  private Complex z1;
  private Complex z2;
  private static final float EPSILON = 0.000001F;

  @BeforeAll
  static void setUpBeforeClass() throws Exception {
    // TODO: add message
    System.out.println("La méthode setUpBeforeClass est bien exécutée avant les tests ");
  }

  @AfterAll
  static void tearDownAfterClass() throws Exception {
    // TODO: add message
    System.out.println("La méthode tearDownAfterClass est bien exécutée après les tests");
  }

  @BeforeEach
  void setUp() throws Exception {
    // TODO: add message
    System.out.println("setUp effectué avant chaque test");
    this.z = new Complex(1.0F, 2.0f);
    this.z1 = new Complex(1.0F, 2.0F);
    this.z2 = new Complex(3.0F, 4.0F);
  }

  @AfterEach
  void tearDown() throws Exception {
    // TODO: add messageDisabled
    System.out.println("tearDown effectué apres chaque test");
  }

  @Test
  void testGetterImaginary() {
    System.out.println("1er test");
    float expected = 2.0F;

    assertThat(z.getImaginaryPart()).as("problem on getter imaginary")
            .isCloseTo(expected, within(EPSILON));


  }

  @Test
  void testGetterReal() {

    float expected = 1.0F;

    assertThat(z.getRealPart()).as("problem on getter real")
            .isCloseTo(expected, within(EPSILON));

  }

  @Test
  void testSetterImaginary() {

    float expected = 3.0F;
    z.setImaginaryPart(expected);
    assertThat(z.getImaginaryPart()).as("problem on setter imaginary")
            .isCloseTo(expected, within(EPSILON));

  }


  @Test
  void testSetterReal() {

    float expected = 3.0F;
    z.setRealPart(expected);
    assertThat(z.getRealPart()).as("problem on setter real")
            .isCloseTo(expected, within(EPSILON));
  }

  @Test
  void testZeroTrue() {
    assertThat(!z.isZero()).as("problem with isZero on Zero Complex number")
            .isTrue();
  }

  @Test
  void testZeroFalse() {
    assertThat(z.isZero()).as("problem with isZero on non Zero Complex number")
            .isFalse();
  }

  @Test
  void testSumReal() {

    float expected = 1.0F + 3.0F;

    Complex z = z1.sum(z2);
    assertThat(z.getRealPart()).as("problem with real part of Sum")
            .isCloseTo(expected, within(EPSILON));
  }

  @Test
  void testSumImaginary() {

    float expected = 2.0F + 4.0F;
    Complex z = z1.sum(z2);
    assertThat(z.getImaginaryPart()).as("problem with imaginary part of Sum")
            .isCloseTo(expected, within(EPSILON));
    System.out.println("Dernier test");
  }

  @Disabled
  @Test
  void testProductReal() {

    float expected = 1.0F * 3.0F - 2.0F * 4.0F;

    Complex z = z1.product(z2);
    assertThat(z.getRealPart()).as("problem with real part of Product")
            .isCloseTo(expected, within(EPSILON));

  }
  @Disabled
  @Test
  void testProductImaginary() {

    float expected = 1.0F * 4.0F + 2.0F * 3.0F;

    z1.product(z2);
    assertThat(z.getImaginaryPart()).as("problem with imaginary part of Product")
            .isCloseTo(expected, within(EPSILON));


  }

  @Disabled
  @Test
  final void testTimeoutInfinite() {
    Complex.infinite();
    fail("NYI");
  }

  @Test
  void testIsRealPartOfInverseIsCorrect(){



  }

  @Test
  void testIsImaginaryPartOfInverseIsCorrect(){

  }
}