// Exercise 3: Comparable, Comparator, and Set semantics
//
// Implement:
//   - Person.compareTo: natural order by age ascending
//   - sortByNameThenAge: sorts a List<Person> by name ascending, then by
//     age ascending for ties, using Comparator.comparing(...).thenComparing(...)
//   - Person.equals/hashCode: two Persons are equal if name AND age match
//     (needed so HashSet dedupes correctly)

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

public class java_collections_framework_exercise_3 {

    static class Person implements Comparable<Person> {
        String name;
        int age;

        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public int compareTo(Person other) {
            // TODO: natural order by age ascending
            return 0;
        }

        @Override
        public boolean equals(Object o) {
            // TODO: implement (name AND age must match)
            return false;
        }

        @Override
        public int hashCode() {
            // TODO: implement using Objects.hash(name, age)
            return 0;
        }

        @Override
        public String toString() {
            return name + "(" + age + ")";
        }
    }

    static List<Person> sortByNameThenAge(List<Person> people) {
        // TODO: implement using Comparator.comparing(...).thenComparing(...)
        // return a NEW sorted list; do not mutate the input
        return null;
    }

    // --- self-check: do not modify below this line ---
    public static void main(String[] args) {
        boolean ok = true;

        Person p1 = new Person("Bob", 30);
        Person p2 = new Person("Ana", 25);
        Person p3 = new Person("Ana", 40);

        List<Person> people = new ArrayList<>(List.of(p1, p2, p3));
        people.sort(null); // natural order via compareTo (Collections would also work)
        ok &= people.get(0) == p2; // age 25
        ok &= people.get(1) == p1; // age 30
        ok &= people.get(2) == p3; // age 40

        List<Person> byName = sortByNameThenAge(new ArrayList<>(List.of(p1, p2, p3)));
        ok &= byName.get(0) == p2; // Ana, 25
        ok &= byName.get(1) == p3; // Ana, 40
        ok &= byName.get(2) == p1; // Bob, 30

        Person dup = new Person("Ana", 25);
        ok &= dup.equals(p2);
        ok &= dup.hashCode() == p2.hashCode();

        Set<Person> set = new HashSet<>(List.of(p1, p2, p3));
        set.add(dup);
        ok &= set.size() == 3; // dup collapses into p2's slot

        System.out.println(ok ? "PASS" : "FAIL");
    }
}
