# CookieJar ADT: Python Versions Test (Extended Mutable)
#
# 34567890123456789012345678901234567890123456789012345678901234567890
#
# 2018-10-10: Initial Python version loosely based on Scala version
# 2018-10-12: Added testing for methods count() and cardinalty()
# 2022-04-20: Improved comments. Reformatted with black.

from typing import List

from cookiejar2 import CookieJarABC, CookieType
from cookiejar_dict2 import CookieJarDict
from cookiejar_list2 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.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(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.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(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.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(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.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(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.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(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.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(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.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(cookie[1])}")
    print()

    print("cj.eat(cookie[1])?")
    cj.eat(cookie[1])
    print(f"cj.is_empty()         = {cj.is_empty()}")
    print(f"cj.cardinality()      = {cj.cardinality()}")
    print(f"cj.has(cookie[0])     = {cj.has(cookie[0])}")
    print(f"cj.has(cookie[1])     = {cj.has(cookie[1])}")
    print(f"cj.count(cookie[0])   = {cj.count(cookie[0])}")
    print(f"cj.count(cookie[1])   = {cj.count(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()
