"""GTIN scalar wire-format laboratory, using unmodified biip==4.0.0.

The native library validates GTIN values, not EANCOM messages or GS1 XML schemas.
Own guards implement two explicitly selected scalar profiles from the GS1 format
note: zero-suppressed n..14, versus exactly14 ASCII digits. Profiles represent
adapter configuration, not an untrusted payload instruction to bypass a rule.
All product/catalogue data is fictional. Valid check digits do not prove GS1
allocation, brand ownership, packaging equivalence or actual product existence.
No real PIM/ERP/registry lookup, connection, product creation or persistence.
"""
from copy import deepcopy
from importlib.metadata import version
import json
import platform
import socket

from biip import EncodeError, ParseError
from biip.gtin import Gtin, gs1_standard_check_digit

CHECKS = []
NATIVE_OBSERVATIONS = []
CONNECTION_ATTEMPTS = []


def check(condition, label):
    if not condition:
        raise AssertionError(label)
    CHECKS.append(label)


def deny_connection(*args, **kwargs):
    CONNECTION_ATTEMPTS.append("blocked")
    raise AssertionError("Network does not belong to this exercise")


socket.create_connection = deny_connection
socket.socket.connect = deny_connection
socket.socket.connect_ex = deny_connection


class RefusedScalar(ValueError):
    pass


def native_gtin(value, label):
    try:
        result = Gtin.parse(value)
    except ParseError as error:
        NATIVE_OBSERVATIONS.append({"case": label, "input": value,
                                    "exception": type(error).__name__, "message": str(error)})
        raise
    NATIVE_OBSERVATIONS.append({"case": label, "input": value,
                                "native_class": type(result).__name__,
                                "native_format": str(result.format),
                                "canonical14": result.as_gtin_14(),
                                "packaging_indicator": result.packaging_level})
    return result


def canonical_from_scalar(raw, profile):
    # A numeric EDIFACT field is not permission to erase the declared transport
    # representation through a JSON integer or an untyped spreadsheet cell.
    if not isinstance(raw, str):
        raise RefusedScalar("scalar_must_be_a_string")
    if not raw or not raw.isascii() or not raw.isdecimal():
        raise RefusedScalar("only_nonempty_ASCII_decimal_scalar_supported")
    if profile == "eancom_numeric":
        if len(raw) > 14 or (len(raw) > 1 and raw.startswith("0")):
            raise RefusedScalar("noncanonical_EANCOM_scalar")
        prepared = raw.zfill(14)
    elif profile == "gs1_xml_14":
        if len(raw) != 14:
            raise RefusedScalar("XML_scalar_requires_exactly14_characters")
        prepared = raw
    else:
        raise RefusedScalar("source_profile_not_qualified")
    result = native_gtin(prepared, "profile:" + profile)
    if type(result) is not Gtin:
        # Regional restricted-circulation formats require another qualified
        # context; do not treat them as ordinary globally exchanged GTINs.
        raise RefusedScalar("native_subtype_requires_another_profile")
    return result.as_gtin_14()


def find_local_reference(raw, profile, catalogue):
    canonical = canonical_from_scalar(raw, profile)
    if canonical not in catalogue:
        raise RefusedScalar("not_in_local_reference_catalogue")
    return {"canonical14": canonical, "local_reference": catalogue[canonical]}


def expect_refusal(call, exception, reason, label):
    try:
        call()
    except exception as error:
        check(str(error) == reason, label)
    else:
        raise AssertionError(label + ": unexpectedly accepted")


def main():
    check(version("biip") == "4.0.0", "pinned native GTIN library")
    # Original fictitious fixture, not an assignment to a real product.
    payload12 = "04567891234"
    gtin12 = payload12 + str(gs1_standard_check_digit(payload12))
    eancom = gtin12.lstrip("0")
    native12 = native_gtin(gtin12, "GTIN12")
    canonical14 = native12.as_gtin_14()
    check(gtin12 == "045678912347", "executed fictitious source value")
    check(eancom == "45678912347" and len(eancom) == 11, "EANCOM scalar has eleven significant digits")
    check(canonical14 == "00045678912347", "native canonical14 retains the same numerical identity")
    check(str(native12.format) == "GTIN-12", "original native type is GTIN12")
    try:
        native_gtin(eancom, "direct_EANCOM11")
    except ParseError as error:
        check("got 11" in str(error), "direct GTIN parser observes unsupported eleven-digit length")
    else:
        raise AssertionError("direct eleven-digit input unexpectedly accepted")
    from14 = native_gtin(canonical14, "canonical14")
    check(str(from14.format) == "GTIN-12", "fourteen-character representation does not make a new GTIN14 product")
    from13 = native_gtin("0" + gtin12, "padded13")
    check(from13.as_gtin_14() == canonical14, "padded13 shares the same canonical identity")
    spaced = native_gtin(" " + gtin12 + " ", "native_outer_spaces")
    check(spaced.as_gtin_14() == canonical14, "native GTIN parser strips outer spaces")
    check(canonical_from_scalar(eancom, "eancom_numeric") == canonical14,
          "qualified EANCOM scalar prepared before native validation")
    check(canonical_from_scalar(canonical14, "gs1_xml_14") == canonical14,
          "qualified XML scalar already exactly fourteen characters")
    before = len(NATIVE_OBSERVATIONS)
    expect_refusal(lambda: canonical_from_scalar(gtin12, "gs1_xml_14"),
                   RefusedScalar, "XML_scalar_requires_exactly14_characters",
                   "native GTIN acceptance alone does not admit a twelve-character XML scalar")
    check(len(NATIVE_OBSERVATIONS) == before, "wrong XML width refused before native GTIN parsing")
    bad_scalars = [
        (gtin12, "eancom_numeric", "noncanonical_EANCOM_scalar", "EANCOM leading zero"),
        (canonical14 + "0", "gs1_xml_14", "XML_scalar_requires_exactly14_characters", "XML fifteen characters"),
        (" " + canonical14 + " ", "gs1_xml_14", "only_nonempty_ASCII_decimal_scalar_supported", "XML outer spaces"),
        ("+" + eancom, "eancom_numeric", "only_nonempty_ASCII_decimal_scalar_supported", "leading plus"),
        ("4.5678912347e10", "eancom_numeric", "only_nonempty_ASCII_decimal_scalar_supported", "scientific notation"),
        ("４５６７８９１２３４７", "eancom_numeric", "only_nonempty_ASCII_decimal_scalar_supported", "non-ASCII digits"),
        (int(eancom), "eancom_numeric", "scalar_must_be_a_string", "JSON integer"),
        (True, "eancom_numeric", "scalar_must_be_a_string", "boolean"),
        ("", "eancom_numeric", "only_nonempty_ASCII_decimal_scalar_supported", "empty scalar"),
        ("1" * 15, "eancom_numeric", "noncanonical_EANCOM_scalar", "EANCOM over fourteen"),
        (eancom, "unqualified", "source_profile_not_qualified", "unknown profile"),
    ]
    for raw, profile, reason, label in bad_scalars:
        before = len(NATIVE_OBSERVATIONS)
        expect_refusal(lambda: canonical_from_scalar(raw, profile), RefusedScalar, reason, label)
        check(len(NATIVE_OBSERVATIONS) == before, label + ": no additional native parse")
    broken_digit = canonical14[:-1] + "8"
    try:
        canonical_from_scalar(broken_digit, "gs1_xml_14")
    except ParseError as error:
        check("check digit" in str(error), "native checksum rejection remains distinct from local catalogue absence")
    else:
        raise AssertionError("invalid check digit accepted")
    restricted = native_gtin("02012345678903", "restricted_circulation")
    check(type(restricted).__name__ == "Rcn", "native restricted-circulation subtype identified")
    expect_refusal(lambda: canonical_from_scalar("02012345678903", "gs1_xml_14"),
                   RefusedScalar, "native_subtype_requires_another_profile",
                   "restricted-circulation code excluded from this local exchange profile")
    catalogue = {canonical14: "PRODUCT-FIXTURE-47"}
    snapshot = deepcopy(catalogue)
    raw_lookup_missed = catalogue.get(eancom)
    check(raw_lookup_missed is None, "raw eleven-digit key misses fictional canonical catalogue")
    a = find_local_reference(eancom, "eancom_numeric", catalogue)
    b = find_local_reference(canonical14, "gs1_xml_14", catalogue)
    check(a == b == {"canonical14": canonical14, "local_reference": "PRODUCT-FIXTURE-47"},
          "two qualified wire representations find the same local reference")
    # A different checksum-valid identifier is a distinct fictitious fixture.
    # Constructing it here does not authorize allocating or changing real GTINs.
    other_payload = "1" + canonical14[1:-1]
    other_value = other_payload + str(gs1_standard_check_digit(other_payload))
    other = native_gtin(other_value, "different_valid_identifier")
    check(other.as_gtin_14() != canonical14, "nonzero first digit is not a filler zero")
    check(str(other.format) == "GTIN-14" and other.packaging_level == 1,
          "native nonzero indicator is retained without inferring a pack quantity")
    try:
        other.as_gtin_13()
    except EncodeError:
        check(True, "native GTIN14 cannot be shortened to GTIN13")
    else:
        raise AssertionError("different native GTIN14 incorrectly shortened")
    expect_refusal(lambda: find_local_reference(other_value, "gs1_xml_14", catalogue),
                   RefusedScalar, "not_in_local_reference_catalogue",
                   "different valid code does not create or reassign a product")
    check(catalogue == snapshot, "fictional catalogue unchanged")
    check(not CONNECTION_ATTEMPTS, "no network connection attempts")
    return {"python": platform.python_version(), "biip": version("biip"),
            "checks_passed": len(CHECKS), "checks": CHECKS,
            "native_parse_runs": len(NATIVE_OBSERVATIONS),
            "native_observations": NATIVE_OBSERVATIONS,
            "source": {"gtin12": gtin12, "eancom_numeric": eancom,
                       "gs1_xml_14": canonical14},
            "raw_local_lookup": raw_lookup_missed, "qualified_local_lookup": a,
            "different_identifier": other_value,
            "real_connection_attempts": len(CONNECTION_ATTEMPTS),
            "real_pim_erp_or_registry_calls": 0, "real_product_writes": 0,
            "local_catalogue_unchanged": catalogue == snapshot,
            "limitations": ["scalar-format and GTIN library example only", "no native EANCOM or XML message/schema validation", "no GS1 allocation/product/pack relationship certificate", "independent pinned library, not latest-version recommendation", "profile configuration and catalogue fictional", "no real PIM/ERP/registry response or write", "in-memory state, no durable receipt"]}


if __name__ == "__main__":
    print(json.dumps(main(), ensure_ascii=False, indent=2))
