#!/usr/bin/env python3
"""Check the order filter in Chromium against a running copy of the lab.

Install: python3 -m pip install playwright
         python3 -m playwright install chromium
Run:     python3 test_order_filter.py http://127.0.0.1:8765/orders
To use another Chromium binary, set CHROMIUM_EXECUTABLE_PATH to its path.
"""

import argparse
import os
import sys
from urllib.parse import parse_qs, urlsplit

from playwright.sync_api import Error, sync_playwright


def check(page, step, status, number, order_ids):
    location = urlsplit(page.url)
    rows = page.locator("tbody tr").evaluate_all(
        "rows => rows.map(row => [...row.cells].map(cell => cell.textContent.trim()))"
    )
    expected_rows = [[order_id, status.title()] for order_id in order_ids]
    has_empty_message = page.get_by_role("status").filter(has_text="No matching orders.").is_visible()
    if (parse_qs(location.query) != {"status": [status], "page": [str(number)]}
            or rows != expected_rows or has_empty_message != (not order_ids)):
        raise AssertionError(
            f"{step}: expected status={status}, page={number}, rows={expected_rows}; "
            f"observed {location.path}?{location.query}, rows={rows}, "
            f"empty_message={has_empty_message}"
        )
    print(f"PASS {step}")


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("url", nargs="?", default="http://127.0.0.1:8765/orders")
    args = parser.parse_args()
    try:
        with sync_playwright() as playwright:
            browser = playwright.chromium.launch(
                executable_path=os.environ.get("CHROMIUM_EXECUTABLE_PATH")
            )
            page = browser.new_page()
            page.set_default_timeout(10000)
            page.goto(args.url)
            page.get_by_role("link", name="Open", exact=True).click()
            check(page, "select Open", "open", 1, ["ORD-101", "ORD-102"])
            page.get_by_role("link", name="Next page", exact=True).click()
            check(page, "next page", "open", 2, ["ORD-105", "ORD-106"])
            page.reload()
            check(page, "reload", "open", 2, ["ORD-105", "ORD-106"])
            page.go_back()
            check(page, "back", "open", 1, ["ORD-101", "ORD-102"])
            page.get_by_role("link", name="Cancelled", exact=True).click()
            check(page, "empty filter", "cancelled", 1, [])
            browser.close()
    except (AssertionError, Error) as error:
        print(f"FAIL {error}", file=sys.stderr)
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main())
