#include <iostream>
#include <cstdlib>
#include <sstream>

#include "complex.h"


void test(Complex a, Complex b, const char* type) {
  if (!(a == b)) {
    std::cout << "Error in " << type << ". expected: " << b;
    std::cout << " got: " << a << std::endl;
    exit(EXIT_FAILURE);
  }
}

void test_equal() {
  test(Complex(1, 5.000000000001), Complex(1, 5), "equal");
  test(Complex(1.000000000001, 5), Complex(1, 5), "equal");
}
void test_multiplication() {
  test(Complex(4, 2) * Complex(1, 5), Complex(-6, 22), "multiplication");
  test(Complex(4, 2) * Complex(0, 5), Complex(-10, 20), "multiplication");
  test(Complex(4, 2) * Complex(2, 0), Complex(8, 4), "multiplication");
  test(Complex(4, 2) * Complex(0, 0), Complex(0, 0), "multiplication");
}
void test_division() {
  test(Complex(4, 2) / Complex(5, 0), Complex((float)4/5, (float)2/5), "division");
  test(Complex(4, 2) / Complex(0, 3), Complex((float)2/3, (float)-4/3), "division");
  test(Complex(4, 2) / Complex(2, 3), Complex((float)14/13, (float)-8/13), "division");
}
void test_addition() {
  Complex x(4, 2);
  test(x += Complex(5, 0), Complex(9, 2), "addition");
  test(x += Complex(-2, 4), Complex(7, 6), "addition");
  test(x += Complex(-4, -2), Complex(3, 4), "addition");
}
void test_subtraction() {
  Complex x(4, 2);
  test(x -= Complex(5, 0), Complex(-1, 2), "subtraction");
  test(x -= Complex(-2, 4), Complex(1, -2), "subtraction");
  test(x -= Complex(-4, -2), Complex(5, 0), "subtraction");
}
void test_istream() {
  Complex x;
  std::stringstream ss("5 -3i");

  ss >> x;
  test(x, Complex(5, -3), "input stream");
}

int main(void) {
  test_equal();

  test_multiplication();
  test_division();

  test_addition();
  test_subtraction();

  test_istream();

  std::cout << "All tests were successful!" << std::endl;

  return EXIT_SUCCESS;
}
