import java.util.*;
import java.util.Scanner;

// Generic interface that defines search and display methods for any type T
interface SearchUtility<T> {
    T search(int id) throws NotFoundException; // Search by ID, throws exception if not found
    void display(T t); // Display the found object
}

// Custom exception class for when items are not found
class NotFoundException extends Exception {

    public NotFoundException(String message) {
        super(message);
    }
}

// Book class to store book details
class Book {

    private int bookId; // Unique identifier for books
    private String title; // Book title
    private String author; // Book author

    // Constructor to initialize book properties
    public Book(int bookId, String title, String author) {
        this.bookId = bookId;
        this.title = title;
        this.author = author;
    }

    // Getter for book ID - needed for searching
    public int getBookId() {
        return bookId;
    }

    // Override toString for proper display format
    @Override
    public String toString() {
        return (
            "Book ID: " + bookId + ", Title: " + title + ", Author: " + author
        );
    }
}

// Student class to store student details
class Student {

    private int regNo; // Registration number for student identification
    private String name; // Student name
    private String course; // Course enrolled

    // Constructor to initialize student properties
    public Student(int regNo, String name, String course) {
        this.regNo = regNo;
        this.name = name;
        this.course = course;
    }

    // Getter for registration number - needed for searching
    public int getRegNo() {
        return regNo;
    }

    // Override toString for proper display format
    @Override
    public String toString() {
        return (
            "Registration No: " +
            regNo +
            ", Name: " +
            name +
            ", Course: " +
            course
        );
    }
}

// Implementation of SearchUtility for Book class
class BookSearch implements SearchUtility<Book> {

    private List<Book> books; // List to store book records

    // Constructor allows user to add books
    public BookSearch() {
        books = new ArrayList<>();
        Scanner scanner = new Scanner(System.in);

        System.out.println("Enter number of books to add:");
        int n = scanner.nextInt();
        scanner.nextLine();

        for (int i = 0; i < n; i++) {
            System.out.println("Enter book ID:");
            int id = scanner.nextInt();
            scanner.nextLine();

            System.out.println("Enter book title:");
            String title = scanner.nextLine();

            System.out.println("Enter book author:");
            String author = scanner.nextLine();

            books.add(new Book(id, title, author));
        }
    }

    // Search implementation for books using book ID
    @Override
    public Book search(int id) throws NotFoundException {
        for (Book book : books) {
            if (book.getBookId() == id) {
                return book;
            }
        }
        throw new NotFoundException("Book not found with ID: " + id);
    }

    // Display implementation for books
    @Override
    public void display(Book book) {
        System.out.println(book);
    }
}

// Implementation of SearchUtility for Student class
class StudentSearch implements SearchUtility<Student> {

    private List<Student> students; // List to store student records

    // Constructor allows user to add students
    public StudentSearch() {
        students = new ArrayList<>();
        Scanner scanner = new Scanner(System.in);

        System.out.println("Enter number of students to add:");
        int n = scanner.nextInt();
        scanner.nextLine();

        for (int i = 0; i < n; i++) {
            System.out.println("Enter registration number:");
            int regNo = scanner.nextInt();
            scanner.nextLine();

            System.out.println("Enter student name:");
            String name = scanner.nextLine();

            System.out.println("Enter course:");
            String course = scanner.nextLine();

            students.add(new Student(regNo, name, course));
        }
    }

    // Search implementation for students using registration number
    @Override
    public Student search(int regNo) throws NotFoundException {
        for (Student student : students) {
            if (student.getRegNo() == regNo) {
                return student;
            }
        }
        throw new NotFoundException(
            "Student not found with Registration No: " + regNo
        );
    }

    // Display implementation for students
    @Override
    public void display(Student student) {
        System.out.println(student);
    }
}

// Thread class for handling book searches
class BookThread extends Thread {

    private BookSearch bookSearch; // Reference to book search utility
    private int bookId; // Book ID to search for

    // Constructor to initialize search parameters
    public BookThread(BookSearch bookSearch, int bookId) {
        this.bookSearch = bookSearch;
        this.bookId = bookId;
    }

    // Thread execution - searches and displays book details
    @Override
    public void run() {
        try {
            Book book = bookSearch.search(bookId);
            bookSearch.display(book);
        } catch (NotFoundException e) {
            System.out.println(e.getMessage());
        }
    }
}

// Thread class for handling student searches
class StudentThread extends Thread {

    private StudentSearch studentSearch; // Reference to student search utility
    private int regNo; // Registration number to search for

    // Constructor to initialize search parameters
    public StudentThread(StudentSearch studentSearch, int regNo) {
        this.studentSearch = studentSearch;
        this.regNo = regNo;
    }

    // Thread execution - searches and displays student details
    @Override
    public void run() {
        try {
            Student student = studentSearch.search(regNo);
            studentSearch.display(student);
        } catch (NotFoundException e) {
            System.out.println(e.getMessage());
        }
    }
}

// Main class to demonstrate concurrent book and student searches
public class TheQ {

    public static void main(String[] args) {
        // Create search utility instances
        BookSearch bookSearch = new BookSearch();
        StudentSearch studentSearch = new StudentSearch();

        Scanner scanner = new Scanner(System.in);

        System.out.println("Enter book ID to search:");
        int bookId = scanner.nextInt();

        System.out.println("Enter student registration number to search:");
        int regNo = scanner.nextInt();

        // Create and start threads for concurrent searching
        BookThread bookThread = new BookThread(bookSearch, bookId);
        StudentThread studentThread = new StudentThread(studentSearch, regNo);

        bookThread.start();
        studentThread.start();

        scanner.close();
    }
}
