package oving4.twitter;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class TweetTest {

	private Tweet retweet1;
	private Tweet tweet;
	private TwitterAccount kari;
	private TwitterAccount nils;
	private TwitterAccount ole;

	@BeforeEach
	public void setUp() {
		nils = new TwitterAccount("Nils");
		ole = new TwitterAccount("Ole");
		kari = new TwitterAccount("Kari");
		tweet = new Tweet(nils, "Kvitre!");
		retweet1 = null;
	}

	@Test
	@DisplayName("Check that the constructor initializes correctly")
	public void testNullInConstructors() {
		assertEquals("Kvitre!", tweet.getText());
		assertEquals(nils, tweet.getOwner());

		assertThrows(IllegalArgumentException.class, () -> {
			new Tweet(null, "Kvitre!");
		}, "The tweet must have an owner");

		assertThrows(IllegalArgumentException.class, () -> {
			new Tweet(nils, (String) null);
		}, "The tweet must have text");

		assertThrows(IllegalArgumentException.class, () -> {
			new Tweet(null, tweet);
		}, "The tweet must have an owner");

		assertThrows(IllegalArgumentException.class, () -> {
			new Tweet(nils, (Tweet) null);
		}, "The tweet must have an original tweet");
	}

	@Test
	public void constructorNewTweet() {
		assertEquals("Kvitre!", tweet.getText(),
				"The constructor initialized the tweet with incorrect text");
		assertEquals(nils, tweet.getOwner(),
				"The constructor initialized the tweet with the wrong owner");
	}

	@Test
	@DisplayName("Check that retweet has the same text but a different owner")
	public void constructorRetweet() {
		retweet1 = new Tweet(ole, tweet);
		assertEquals("Kvitre!", retweet1.getText());
		assertEquals(ole, retweet1.getOwner());

		assertThrows(RuntimeException.class, () -> {
			new Tweet(nils, tweet);
		}, "A person should not be able to retweet themselves");
	}

	@Test
	@DisplayName("Check that the original tweet is always correct")
	public void getOriginalTweet() {
		assertNull(tweet.getOriginalTweet());

		retweet1 = new Tweet(ole, tweet);
		assertEquals(tweet, retweet1.getOriginalTweet());
		assertEquals(retweet1.getOriginalTweet().getText(), retweet1.getText());
		assertEquals(tweet, retweet1.getOriginalTweet());
		assertEquals(retweet1.getOriginalTweet().getText(), retweet1.getText());
	}

	@Test
	@DisplayName("Check that retweet count increases when a tweet is retweeted")
	public void getRetweetCount() {
		assertEquals(0, tweet.getRetweetCount());

		new Tweet(ole, tweet);
		assertEquals(1, tweet.getRetweetCount());

		new Tweet(kari, tweet);
		assertEquals(2, tweet.getRetweetCount());
	}
}
