// Part 1


// Defines a class called "Book" that represents a book with a title and an ID
public class Book {
    private String title;
    private int id;
    private static int bookCount = 0;

    // One-argument constructor for title
    // The ID is automatically assigned when a new book object is created, and it is incremented for each new book created
    public Book(String title) {
        this.title = title;
        this.id = ++bookCount;
    }

    // Getter for BookCount
    //static variable called "bookCount", which keeps track of the total number of books created
    public static int getBookCount() {
        return bookCount;
    }

    // Override toString() method to return title
    @Override
    public String toString() {
        return this.title;
    }
    // Tester Method
    // tester method called "main()" which creates two book objects, prints out their IDs and titles, also prints out the total book in library as well
    public static void main(String[] args) {
        Book book1 = new Book("Boy With The Striped Pajamas");
        Book book2 = new Book("Refugee");

        System.out.println("Book 1 ID: " + book1.id);
        System.out.println("Book 1 Title: " + book1.toString());
        System.out.println("Book 2 ID: " + book2.id);
        System.out.println("Book 2 Title: " + book2.toString());
        System.out.println("Total books in library: " + Book.getBookCount());
    }
}
//Executes all code within book class to work
Book.main(null);
Book 1 ID: 1
Book 1 Title: Boy With The Striped Pajamas
Book 2 ID: 2
Book 2 Title: Refugee
Total books in library: 2
// Part 2
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Book {
    //These are where the instance variables are created, fulfilling part 2
    private String title;
    private LocalDate publicationDate;
    private int shelfLife;

    public Book(String title, LocalDate publicationDate) {
        this.title = title;
        this.publicationDate = publicationDate;
        this.shelfLife = calculateShelfLife();
    }
    //This is where we calculate the shelf Life of a book, fulfilling part 3. 
    private int calculateShelfLife() {
        LocalDate today = LocalDate.now();
        long daysSincePublication = ChronoUnit.DAYS.between(publicationDate, today);
        return (int)daysSincePublication;
    }

    public int getShelfLife() {
        return shelfLife;
    }

    //This is where a boolean method (true/false) is created to determine whether or not the book should come off the shelf and in this situation it comes off the shelf if the shelfLife is greater than or equal to 365
    public boolean shouldRemoveFromShelf() {
        return shelfLife >= 365;
    }
}

//This is where part 1 is fulfilled, as the novel and textbook class extend from Book and are created here
public class Novel extends Book {
    private String author;

    public Novel(String title, LocalDate publicationDate, String author) {
        super(title, publicationDate);
        this.author = author;
    }

    public String getAuthor() {
        return author;
    }
}

//This is where part 1 is fulfilled, as the novel and textbook class extend from Book and are created here
public class Textbook extends Book {
    private String publishingCompany;

    public Textbook(String title, LocalDate publicationDate, String publishingCompany) {
        super(title, publicationDate);
        this.publishingCompany = publishingCompany;
    }

    public String getPublishingCompany() {
        return publishingCompany;
    }
}

//This is where the Book Tester is (part 5, tests everything in parts 1-3)
public class BookTester {
    public static void main(String[] args) {
        LocalDate publicationDate = LocalDate.of(2010, 1, 1);

        Novel novel = new Novel("Big Nate", publicationDate, "Lincoln Pierce");
        System.out.println(novel.getAuthor());
        System.out.println(novel.getShelfLife());
        System.out.println(novel.shouldRemoveFromShelf());

        Textbook textbook = new Textbook("Advanced Algorithms", publicationDate, "Mr. Mortensen");
        System.out.println(textbook.getPublishingCompany());
        System.out.println(textbook.getShelfLife());
        System.out.println(textbook.shouldRemoveFromShelf());
    }
}
BookTester.main(null);
Lincoln Pierce
4857
true
Mr. Mortensen
4857
true
//Part 3

import java.util.ArrayList;

public class BookShelf {
    public static void main(String[] args) throws InterruptedException {
        // Construct some books and add them to a library
        ArrayList<Book> library = new ArrayList<>();
        library.add(new TextBook("Diary Of A Wimpy Kid"));
        library.add(new Novel("Refugee"));
        library.add(new Novel("Boy With The Striped Pajamas"));

        // Let's wait for 5 seconds (5000 milliseconds) to pass
        Thread.sleep(5000);

        // Check which books need to be removed from the shelf
        for (Book book : library) {
            if (book.isExpired()) {
                System.out.println(book.getTitle() + " - Expired");
            } else {
                System.out.println(book.getTitle() + " - Available");
            }
        }
    }
}

public abstract class Book {
    private String title;
    private long constructionTime;

    public Book(String title) {
        this.title = title;
        this.constructionTime = System.nanoTime();
    }

    public String getTitle() {
        return title;
    }

    public long getConstructionTime() {
        return constructionTime;
    }

    public long getShelfLife() {
        long currentTime = System.nanoTime();
        long shelfLife = currentTime - constructionTime;
        return shelfLife;
    }

    public abstract boolean isExpired();
}

public class TextBook extends Book {
    private static final long SHELF_LIFE = 3000;

    public TextBook(String title) {
        super(title);
    }

    public boolean isExpired() {
        long shelfLife = getShelfLife();
        return shelfLife > SHELF_LIFE;
    }
}

public class Novel extends Book {
    private static final long SHELF_LIFE = 365 * 24 * 60 * 60 * 1000000000L; // 1 year in nanoseconds
    private int returnStamps = 0;

    public Novel(String title) {
        super(title);
    }

    public void addReturnStamp() {
        returnStamps++;
    }

    public boolean isExpired() {
        long shelfLife = getShelfLife();
        long shelfLifeLeft = SHELF_LIFE - shelfLife;

        if (shelfLifeLeft <= 0) {
            return true;
        } else {
            long renewalThreshold = 3 * 365 * 24 * 60 * 60 * 1000000000L; // 3 years in nanoseconds
            if (returnStamps >= 3 && shelfLifeLeft <= renewalThreshold) {
                returnStamps = 0;
                return false;
            } else {
                return true;
            }
        }
    }
}
BookShelf.main(null);
Diary Of A Wimpy Kid - Available
Refugee - Available
Boy With The Striped Pajamas - Available