/**
 * Represents a recursively-defined linked list, containing a reference to
 * a list element and a reference to a sublist representing the rest of the
 * list.  An empty list has a null reference for both the list element and
 * the sublist.
 *
 * @Author Nathan Sprague (April 2010)
 * @Author Alyce Brady
 * @version Sept 28, 2025
 */
public class K_RecList<T>
{
    private T element; 
    private K_RecList<T> next;

    /**
     * Creates an empty list.
     */
    public K_RecList()
    {
        this.element = null;
        this.next = null;
    }

    /**
     * Creates a list with a single element.
     * @param element - the element that the list will contain
     */
    public K_RecList(T element)
    {
        this.element = element;
        this.next = new K_RecList<>();
    }

    /**
     * Creates a list composed of an element and a list.
     * @param element - the element that the list will have at the head
     */
    public K_RecList(T element, K_RecList<T> list)
    {
        this.element = element;
        this.next = list;
    }

    /**
     * Returns the head of the list.
     */
    public T head()
    {
        return this.element;
    }

    /**
     * Returns the tail of the list (the list following the head).
     */
    public K_RecList<T> tail()
    {
        // If the list is empty, return the empty list.
        // Otherwise return the list following the head.
        return isEmpty() ? this : this.next;
    }

    /**
     * Returns true if the list is empty; false otherwise.
     * An empty list has a null reference for both the list element and
     * the sublist.
     */
    public boolean isEmpty()
    {
        // YOU NEED TO ADD CODE HERE!
        return true;  // dummy stub code so it will compile
    }

    /**
     * Returns the number of elements in the list.
     * (This method uses the ?: if expression rather than an if statement
     *  to make it more functional in nature.)
     */
    public int size()
    {
        return isEmpty() ? 0 : tail().size() + 1;
    }

    /**
     * Returns a string of space-separated elements in the list.
     * 
     * @return a string representing the elements in the list
     */
    @Override
    public String toString()
    {
        if ( isEmpty() )
            return "";

        return head().toString() + " " + tail().toString();
    }

    public K_RecList<T> newWithAppendedElt(T eltToAppend)
    {
        // YOU NEED TO ADD CODE HERE!
        return this;  // dummy stub code so it will compile
    }

    public K_RecList<T> newWithAppendedList(K_RecList<T> listToAppend)
    {
        // YOU NEED TO ADD CODE HERE!
        return this;  // dummy stub code so it will compile
    }

    public T getElement(int index)
    {
        // YOU NEED TO ADD CODE HERE!
        return head();  // dummy stub code so it will compile
    }

}
