package com.uwetrottmann.tmdb.services;

import com.uwetrottmann.tmdb.BaseTestCase;
import com.uwetrottmann.tmdb.entities.Person;
import com.uwetrottmann.tmdb.entities.PersonCastCredit;
import com.uwetrottmann.tmdb.entities.PersonCredits;
import com.uwetrottmann.tmdb.entities.PersonCrewCredit;
import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

public class PersonServiceTest extends BaseTestCase {

    private static final SimpleDateFormat JSON_STRING_DATE = new SimpleDateFormat("yyy-MM-dd");

    @Test
    public void test_summary() throws ParseException {
        Person person = getManager().personService().summary(287);
        assertNotNull("Result was null.", person);
        assertEquals("Person name does not match.", "Brad Pitt", person.name);
        assertNotNull("Person homepage was null", person.homepage);
        assertNotNull("Person TMDB ID was null.", person.id);
        assertNotNull("Person biography was null.", person.biography);
        assertEquals("Person birthday does not match.", JSON_STRING_DATE.parse("1963-12-18"),
                person.birthday);
        assertNull("Person deathday does not match", person.deathday);
        assertNotNull("Person place of birth does not match", person.place_of_birth);
        assertNotNull("Movie profile path was null.", person.profile_path);
    }

    @Test
    public void test_movie_credits() {
        PersonCredits credits = getManager().personService().movieCredits(287, null);
        assertPersonCredits(credits, false);

        for (PersonCastCredit credit : credits.cast) {
            assertThat(credit.title).isNotEmpty();
        }
    }

    @Test
    public void test_tv_credits() {
        PersonCredits credits = getManager().personService().tvCredits(287, null);
        assertPersonCredits(credits, false);

        for (PersonCastCredit credit : credits.cast) {
            assertThat(credit.episode_count).isGreaterThanOrEqualTo(0);
            assertThat(credit.name).isNotEmpty();
        }
    }

    @Test
    public void test_combined_credits() {
        PersonCredits credits = getManager().personService().combinedCredits(287, null);
        assertPersonCredits(credits, true);
    }

    private void assertPersonCredits(PersonCredits credits, boolean hasMediaType) {
        assertThat(credits.id).isEqualTo(287);

        // assert cast credits
        assertThat(credits.cast).isNotEmpty();
        for (PersonCastCredit credit : credits.cast) {
            assertThat(credit.character).isNotNull(); // may be empty

            if (hasMediaType) {
                assertThat(credit.media_type).isNotEmpty();
            }
        }

        // assert crew credits
        assertThat(credits.crew).isNotEmpty();
        for (PersonCrewCredit credit : credits.crew) {
            // may be empty, but should exist
            assertThat(credit.department).isNotNull();
            assertThat(credit.job).isNotNull();

            if (hasMediaType) {
                assertThat(credit.media_type).isNotEmpty();
            }
        }
    }

}

@@ -1698,38 +1698,126 @@
 ;%0A        assert
-Person
+That(credits.id).isEqualTo(287);%0A        assertCastCredits(credits, false);%0A        assertCrew
 Credits(credits,
@@ -2084,38 +2084,83 @@
 ;%0A        assert
-Person
+That(credits.id).isEqualTo(287);%0A        assertCast
 Credits(credits,
@@ -2514,30 +2514,117 @@
       assert
-Person
+That(credits.id).isEqualTo(287);%0A        assertCastCredits(credits, true);%0A        assertCrew
 Credits(cred
@@ -2665,22 +2665,20 @@
 d assert
-Person
+Cast
 Credits(
@@ -2728,56 +2728,8 @@
 ) %7B%0A
-        assertThat(credits.id).isEqualTo(287);%0A%0A
     
@@ -3040,24 +3040,112 @@
 %7D%0A        %7D%0A
+    %7D%0A%0A    private void assertCrewCredits(PersonCredits credits, boolean hasMediaType) %7B
 %0A        // 

Fix up person tv credits test.