"""Synthetic workload invariants. No kubectl, network, cluster or file writes.
Not a Kubernetes API validator, scheduler simulator or security certification.
Run: python3 parcelops_workload_lab.py
"""
import copy
import unittest

DEPLOYMENT = {"apiVersion": "apps/v1", "kind": "Deployment",
 "metadata": {"name": "parcelops", "namespace": "handbook-lab"},
 "spec": {"replicas": 2, "selector": {"matchLabels": {"app": "parcelops"}},
 "template": {"metadata": {"labels": {"app": "parcelops"}}, "spec": {
 "automountServiceAccountToken": False,
 "securityContext": {"runAsNonRoot": True, "seccompProfile": {"type": "RuntimeDefault"}},
 "containers": [{"name": "api", "image": "registry.example/parcelops/api:reviewed-version",
 "ports": [{"containerPort": 8080}],
 "resources": {"requests": {"cpu": "100m", "memory": "128Mi"}, "limits": {"cpu": "500m", "memory": "256Mi"}},
 "securityContext": {"allowPrivilegeEscalation": False, "capabilities": {"drop": ["ALL"]}}}]}}}}
SERVICE = {"apiVersion": "v1", "kind": "Service",
 "metadata": {"name": "parcelops", "namespace": "handbook-lab"},
 "spec": {"selector": {"app": "parcelops"}, "ports": [{"port": 80, "targetPort": 8080}], "type": "ClusterIP"}}

def selected(selector, labels):
    return all(labels.get(key) == value for key, value in selector.items())

def fixture_issues(deployment, service):
    """Check only the named fixture pattern; not general Kubernetes validity."""
    issues = []
    template = deployment["spec"]["template"]
    pod = template["spec"]
    labels = template["metadata"]["labels"]
    if deployment["metadata"]["namespace"] != service["metadata"]["namespace"]: issues.append("namespace mismatch")
    if not selected(deployment["spec"]["selector"]["matchLabels"], labels): issues.append("deployment selector mismatch")
    if not selected(service["spec"]["selector"], labels): issues.append("service selector mismatch")
    ports = {p["containerPort"] for c in pod["containers"] for p in c.get("ports", [])}
    if any(p["targetPort"] not in ports for p in service["spec"]["ports"]): issues.append("target port mismatch")
    if pod.get("automountServiceAccountToken") is not False: issues.append("unneeded API token")
    if pod.get("securityContext", {}).get("runAsNonRoot") is not True: issues.append("non-root intent missing")
    if pod.get("securityContext", {}).get("seccompProfile", {}).get("type") != "RuntimeDefault": issues.append("fixture seccomp intent missing")
    for container in pod["containers"]:
        requests = container.get("resources", {}).get("requests", {})
        if not all(name in requests for name in ("cpu", "memory")): issues.append("resource request missing")
        context = container.get("securityContext", {})
        if context.get("allowPrivilegeEscalation") is not False: issues.append("privilege escalation not denied")
        if "ALL" not in context.get("capabilities", {}).get("drop", []): issues.append("capability drop missing")
    return issues

def aggregate_fixture_requests(replicas, cpu_m, memory_mi):
    """Simple arithmetic, not Kubernetes quantity parsing or scheduling."""
    if any(type(x) is not int or x < 0 for x in (replicas, cpu_m, memory_mi)): raise ValueError("Expected nonnegative integers")
    return {"cpu_m": replicas * cpu_m, "memory_mi": replicas * memory_mi}

def conceptual_disruption_allowance(healthy, minimum):
    return max(0, healthy - minimum)

class WorkloadTests(unittest.TestCase):
    def setUp(self): self.d = copy.deepcopy(DEPLOYMENT); self.s = copy.deepcopy(SERVICE)
    def test_baseline(self): self.assertEqual(fixture_issues(self.d, self.s), [])
    def test_service_label(self):
        self.s["spec"]["selector"]["app"] = "typo"; self.assertIn("service selector mismatch", fixture_issues(self.d, self.s))
    def test_deployment_label(self):
        self.d["spec"]["selector"]["matchLabels"]["app"] = "typo"; self.assertIn("deployment selector mismatch", fixture_issues(self.d, self.s))
    def test_namespace(self):
        self.s["metadata"]["namespace"] = "other"; self.assertIn("namespace mismatch", fixture_issues(self.d, self.s))
    def test_port(self):
        self.s["spec"]["ports"][0]["targetPort"] = 9090; self.assertIn("target port mismatch", fixture_issues(self.d, self.s))
    def test_api_token(self):
        self.d["spec"]["template"]["spec"]["automountServiceAccountToken"] = True; self.assertIn("unneeded API token", fixture_issues(self.d, self.s))
    def test_nonroot(self):
        del self.d["spec"]["template"]["spec"]["securityContext"]["runAsNonRoot"]; self.assertIn("non-root intent missing", fixture_issues(self.d, self.s))
    def test_seccomp(self):
        self.d["spec"]["template"]["spec"]["securityContext"]["seccompProfile"]["type"] = "Unconfined"; self.assertIn("fixture seccomp intent missing", fixture_issues(self.d, self.s))
    def test_request(self):
        del self.d["spec"]["template"]["spec"]["containers"][0]["resources"]["requests"]["cpu"]; self.assertIn("resource request missing", fixture_issues(self.d, self.s))
    def test_escalation(self):
        self.d["spec"]["template"]["spec"]["containers"][0]["securityContext"]["allowPrivilegeEscalation"] = True; self.assertIn("privilege escalation not denied", fixture_issues(self.d, self.s))
    def test_capabilities(self):
        self.d["spec"]["template"]["spec"]["containers"][0]["securityContext"]["capabilities"]["drop"] = []; self.assertIn("capability drop missing", fixture_issues(self.d, self.s))
    def test_aggregate(self): self.assertEqual(aggregate_fixture_requests(2, 100, 128), {"cpu_m": 200, "memory_mi": 256})
    def test_surge_capacity(self): self.assertEqual(aggregate_fixture_requests(3, 100, 128)["cpu_m"], 300)
    def test_invalid_arithmetic(self):
        with self.assertRaises(ValueError): aggregate_fixture_requests(-1, 100, 128)
    def test_disruption(self): self.assertEqual(conceptual_disruption_allowance(2, 1), 1)
    def test_exhausted_disruption(self): self.assertEqual(conceptual_disruption_allowance(1, 1), 0)

if __name__ == "__main__":
    unittest.main(verbosity=2)
