# CookieJar ADT: Python Versions Test for Standard Mutable ADTs
#
# 34567890123456789012345678901234567890123456789012345678901234567890
#
# 2018-10-10: Initial Python version loosely based on Scala version
# 2018-10-11: Repaired references to CookieJar classes
# 2022-04-20: Improved comments. Reformatted with black.

from typing import List

from cookiejar import CookieJarABC, CookieType
from cookiejar_dict import CookieJarDict
from cookiejar_list import CookieJarList

# Function testCookieJar takes an empty CookieJar object (any subclass
# of CookieJarABC[CookieType]) and a list of two distinct cookie
# types from CookieType. It runs a series of tests of the CookieJar
# methods using the two test cookies.


def testCookieJar(
    cj: CookieJarABC[CookieType], cookie: List[CookieType]
) -> None:

    print(f"cj                    = {cj}")
    print(f"cj.is_empty()         = {cj.is_empty()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print()

    cj.put_in(cookie[0])
    print(f"cj.put_in(cookie[0])  = {cj}")
    print(f"cj.is_empty()         = {cj.is_empty()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print()

    cj.put_in(cookie[1])
    print(f"cj.put_in(cookie[1])   = {cj}")
    print(f"cj.is_empty()          = {cj.is_empty()}")
    print(f"cj.has(cookie[0])      = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])      = {cj.has(cookie[1])}")
    print()

    cj.put_in(cookie[0])
    print(f"cj.put_in(cookie[0])   = {cj}")
    print(f"cj.is_empty()          = {cj.is_empty()}")
    print(f"cj.has(cookie[0])      = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])      = {cj.has(cookie[1])}")
    print()

    cj.eat(cookie[0])
    print(f"cj.eat(cookie[0])      = {cj}")
    print(f"cj.is_empty()          = {cj.is_empty()}")
    print(f"cj.has(cookie[0])      = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])      = {cj.has(cookie[1])}")
    print()

    cj.eat(cookie[0])
    print(f"cj.eat(cookie[0])      = {cj}")
    print(f"cj.is_empty()          = {cj.is_empty()}")
    print(f"cj.has(cookie[0])      = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])      = {cj.has(cookie[1])}")
    print()

    cj.eat(cookie[1])
    print(f"cj.eat(cookie[1])      = {cj}")
    print(f"cj.is_empty()          = {cj.is_empty()}")
    print(f"cj.has(cookie[0])      = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])      = {cj.has(cookie[1])}")
    print()

    print("cj.eat(cookie[1])?")
    cj.eat(cookie[1])
    print(f"cj                     = {cj}")
    print(f"cj.is_empty()          = {cj.is_empty()}")
    print(f"cj.has(cookie[0])      = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])      = {cj.has(cookie[1] )}")
    print()


# Function run_all_tests executes testCookieJar on the various
# implementations of CookieJar.


def run_all_tests() -> None:

    print("\nBegin CookieJar test.\n")

    test_cookies: List[str] = ["Cookie0", "Cookie1"]
    jar: CookieJarABC[str]  # generic type paramenter = str

    # Test CookJarDict, dictionary-based CookieJar subclass
    print("Begin CookieJarDict test.\n")
    jar = CookieJarDict[str]()
    print("jar = CookieJarDict[str]()")
    testCookieJar(jar, test_cookies)
    print("End CookieJarDict test.\n")

    # Test CookJarList, unordered list-based CookieJar subclass
    print("Begin CookieJarList test.\n")
    jar = CookieJarList[str]()
    print("jar = CookieJarList[str]()")
    testCookieJar(jar, test_cookies)
    print("End CookieJarList test.\n")

    print("End CookieJar test.\n")


if __name__ == "__main__":
    run_all_tests()
