#!/usr/bin/env python3
"""Validate an OpenPMX Lite feed against the XSD and publish rules."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

from lxml import etree, isoschematron


SCHEMA_DIR = Path(__file__).resolve().parent


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("feed", type=Path, help="RSS 2.0 feed XML file")
    args = parser.parse_args()
    xml_parser = etree.XMLParser(resolve_entities=False, no_network=True)

    try:
        document = etree.parse(str(args.feed), xml_parser)
        xml_schema = etree.XMLSchema(
            etree.parse(str(SCHEMA_DIR / "openpmxlite-rss.xsd"), xml_parser)
        )
        if not xml_schema.validate(document):
            print("XSD validation failed:", file=sys.stderr)
            for error in xml_schema.error_log:
                print(error, file=sys.stderr)
            return 1

        rules = isoschematron.Schematron(
            etree.parse(str(SCHEMA_DIR / "openpmxlite.sch"), xml_parser),
            store_report=True,
        )
        if not rules.validate(document):
            print("OpenPMX Lite publish rules failed:", file=sys.stderr)
            namespaces = {"svrl": "http://purl.oclc.org/dsdl/svrl"}
            failed = rules.validation_report.xpath("//svrl:failed-assert", namespaces=namespaces)
            for assertion in failed:
                message = " ".join("".join(assertion.itertext()).split())
                print(f"- {message}", file=sys.stderr)
            return 1
    except (OSError, etree.XMLSyntaxError, etree.XMLSchemaParseError, etree.SchematronParseError) as error:
        print(f"Validation could not run: {error}", file=sys.stderr)
        return 2

    print(f"Valid OpenPMX Lite feed: {args.feed}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
