// Path: RxPractice/app/src/main/java/ru/samples/itis/rxpractice/content/Person.java
// public class Person {
// 
//     private final String mName;
//     private final int mAge;
// 
//     public Person(@NonNull String name, int age) {
//         mName = name;
//         mAge = age;
//     }
// 
//     @NonNull
//     public String getName() {
//         return mName;
//     }
// 
//     public int getAge() {
//         return mAge;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) {
//             return true;
//         }
//         if (o == null || getClass() != o.getClass()) {
//             return false;
//         }
// 
//         Person person = (Person) o;
//         return getAge() == person.getAge() && getName().equals(person.getName());
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = getName().hashCode();
//         result = 31 * result + getAge();
//         return result;
//     }
// 
//     @Override
//     public String toString() {
//         return "Person{" +
//                 "mName='" + mName + '\'' +
//                 ", mAge=" + mAge +
//                 '}';
//     }
// 
//     public int intValue() {
//         return getName().length() + getAge();
//     }
// 
//     @NonNull
//     public Person makeChild(@NonNull Person person) {
//         String name = getName() + " : " + person.getName();
//         return new Person(name, 0);
//     }
// 
//     @NonNull
//     public static Person randomPerson() {
//         Random random = new SecureRandom();
//         final String template = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
//                 "abcdefghijklmnopqrstuvwxyz";
// 
//         String name = randomString(random, template, random.nextInt(15) + 3);
//         int age = random.nextInt(100);
//         return new Person(name, age);
//     }
// 
//     @NonNull
//     public static List<Person> randomPersonsList(int size) {
//         List<Person> list = new ArrayList<>(size);
//         for (int i = 0; i < size; i++) {
//             list.add(randomPerson());
//         }
//         return list;
//     }
// 
//     @NonNull
//     private static String randomString(Random random, String characters, int length) {
//         char[] text = new char[length];
//         for (int i = 0; i < length; i++) {
//             text[i] = characters.charAt(random.nextInt(characters.length()));
//         }
//         return new String(text);
//     }
// }
// 
// Path: RxPractice/app/src/main/java/ru/samples/itis/rxpractice/tasks/RxJavaTask4.java
// public class RxJavaTask4 {
// 
//     /**
//      * TODO : implement this method
//      *
//      * This method takes 4 list of persons - you should return one single observable of persons
//      * 1) Merge (concat) two fathers list into single fathers observable
//      * 2) Repeat step 1 for mothers lists
//      * 3) Using these 2 observables create observable of children using Person#makeChild method
//      *
//      * @param fathers1 - first fathers list
//      * @param fathers2 - second fathers list
//      * @param mothers1 - first mothers list
//      * @param mothers2 - second mothers list
//      * @return children list from merged fathers and mothers
//      */
//     @NonNull
//     public static Observable<Person> task4Observable(@NonNull List<Person> fathers1,
//                                                      @NonNull List<Person> fathers2,
//                                                      @NonNull List<Person> mothers1,
//                                                      @NonNull List<Person> mothers2) {
//         throw new RuntimeException("Observable not implemented exception");
//     }
// 
// }


import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import ru.samples.itis.rxpractice.content.Person;
import ru.samples.itis.rxpractice.tasks.RxJavaTask4;
import rx.Observable;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;

        List<Person> mothers1 = new ArrayList<>();
        mothers1.add(new Person("Mother1", 23));

        List<Person> mothers2 = new ArrayList<>();
        mothers2.add(new Person("Mother2", 26));

        Observable<Person> observable = RxJavaTask4.task4Observable(fathers1, fathers2,
                mothers1, mothers2);

        observable.count().subscribe(integer -> assertEquals(integer.intValue(), 2));

        Person child1 = new Person("Father1 : Mother1", 0);
        Person child2 = new Person("Father2 : Mother2", 0);
        Observable<Person> expected = Observable.just(child1, child2);

        Observable.zip(observable, expected, Person::equals)
                .subscribe(Assert::assertTrue);
    }

    @Test
    public void testInputRandom() throws Exception {
        Random random = new SecureRandom();
        int first = random.nextInt(100) + 50;
        int second = random.nextInt(100) + 50;
        List<Person> fathers1 = Person.randomPersonsList(first);
        List<Person> fathers2 = Person.randomPersonsList(second);
        List<Person> mothers1 = Person.randomPersonsList(first);
        List<Person> mothers2 = Person.randomPersonsList(second);

// Path: RxPractice/app/src/main/java/ru/samples/itis/rxpractice/content/Person.java
// public class Person {
// 
//     private final String mName;
//     private final int mAge;
// 
//     public Person(@NonNull String name, int age) {
//         mName = name;
//         mAge = age;
//     }
// 
//     @NonNull
//     public String getName() {
//         return mName;
//     }
// 
//     public int getAge() {
//         return mAge;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) {
//             return true;
//         }
//         if (o == null || getClass() != o.getClass()) {
//             return false;
//         }
// 
//         Person person = (Person) o;
//         return getAge() == person.getAge() && getName().equals(person.getName());
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = getName().hashCode();
//         result = 31 * result + getAge();
//         return result;
//     }
// 
//     @Override
//     public String toString() {
//         return "Person{" +
//                 "mName='" + mName + '\'' +
//                 ", mAge=" + mAge +
//                 '}';
//     }
// 
//     public int intValue() {
//         return getName().length() + getAge();
//     }
// 
//     @NonNull
//     public Person makeChild(@NonNull Person person) {
//         String name = getName() + " : " + person.getName();
//         return new Person(name, 0);
//     }
// 
//     @NonNull
//     public static Person randomPerson() {
//         Random random = new SecureRandom();
//         final String template = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
//                 "abcdefghijklmnopqrstuvwxyz";
// 
//         String name = randomString(random, template, random.nextInt(15) + 3);
//         int age = random.nextInt(100);
//         return new Person(name, age);
//     }
// 
//     @NonNull
//     public static List<Person> randomPersonsList(int size) {
//         List<Person> list = new ArrayList<>(size);
//         for (int i = 0; i < size; i++) {
//             list.add(randomPerson());
//         }
//         return list;
//     }
// 
//     @NonNull
//     private static String randomString(Random random, String characters, int length) {
//         char[] text = new char[length];
//         for (int i = 0; i < length; i++) {
//             text[i] = characters.charAt(random.nextInt(characters.length()));
//         }
//         return new String(text);
//     }
// }
// 
// Path: RxPractice/app/src/main/java/ru/samples/itis/rxpractice/tasks/RxJavaTask4.java
// public class RxJavaTask4 {
// 
//     /**
//      * TODO : implement this method
//      *
//      * This method takes 4 list of persons - you should return one single observable of persons
//      * 1) Merge (concat) two fathers list into single fathers observable
//      * 2) Repeat step 1 for mothers lists
//      * 3) Using these 2 observables create observable of children using Person#makeChild method
//      *
//      * @param fathers1 - first fathers list
//      * @param fathers2 - second fathers list
//      * @param mothers1 - first mothers list
//      * @param mothers2 - second mothers list
//      * @return children list from merged fathers and mothers
//      */
//     @NonNull
//     public static Observable<Person> task4Observable(@NonNull List<Person> fathers1,
//                                                      @NonNull List<Person> fathers2,
//                                                      @NonNull List<Person> mothers1,
//                                                      @NonNull List<Person> mothers2) {
//         throw new RuntimeException("Observable not implemented exception");
//     }
// 
// }


// Path: RxPractice/app/src/test/java/ru/samples/itis/rxpractice/Task4Test.java
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import ru.samples.itis.rxpractice.content.Person;
import ru.samples.itis.rxpractice.tasks.RxJavaTask4;
import rx.Observable;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;


        List<Person> mothers1 = new ArrayList<>();
        mothers1.add(new Person("Mother1", 23));

        List<Person> mothers2 = new ArrayList<>();
        mothers2.add(new Person("Mother2", 26));

        Observable<Person> observable = RxJavaTask4.task4Observable(fathers1, fathers2,
                mothers1, mothers2);

        observable.count().subscribe(integer -> assertEquals(integer.intValue(), 2));

        Person child1 = new Person("Father1 : Mother1", 0);
        Person child2 = new Person("Father2 : Mother2", 0);
        Observable<Person> expected = Observable.just(child1, child2);

        Observable.zip(observable, expected, Person::equals)
                .subscribe(Assert::assertTrue);
    }

    @Test
    public void testInputRandom() throws Exception {
        Random random = new SecureRandom();
        int first = random.nextInt(100) + 50;
        int second = random.nextInt(100) + 50;
        List<Person> fathers1 = Person.randomPersonsList(first);
        List<Person> fathers2 = Person.randomPersonsList(second);
        List<Person> mothers1 = Person.randomPersonsList(first);
        List<Person> mothers2 = Person.randomPersonsList(second);

        Observable<Person> observable = RxJavaTask4.task4Observable(fathers1, fathers2,