from __future__ import annotations

import unittest

from Aspidites._vendor.apm import *


class CaptureTest(unittest.TestCase):
    def test_multi_capture(self):
        result = match(
            value=[
                {
                    "first-name": "Jane",
                    "last-name": "Doe",
                },
                {
                    "first-name": "John",
                    "last-name": "Doe",
                },
            ],
            pattern=Each({"first-name": Capture(..., name="first_names")}),
            multimatch=True,
        )
        self.assertTrue(result)
        self.assertEqual(["Jane", "John"], result["first_names"])

    def test_last_capture(self):
        result = match(
            multimatch=False,
            value=[
                {
                    "first-name": "Jane",
                    "last-name": "Doe",
                },
                {
                    "first-name": "John",
                    "last-name": "Doe",
                },
            ],
            pattern=Each({"first-name": Capture(..., name="first_name")}),
        )
        self.assertTrue(result)
        self.assertEqual("John", result["first_name"])

    def test_syntactic_sugar_rshift_operator(self):
        result = match(
            sample_k8s_response,
            {
                "containers": Each(
                    {
                        "image": _ >> "image",
                        "name": _ >> "name",
                        "ports": Each({"containerPort": _ >> "port"}),
                    }
                )
            },
        )
        self.assertTrue(result)
        self.assertEqual(
            "k8s.gcr.io/metrics-server/metrics-server:v0.4.1", result["image"]
        )
        self.assertEqual("metrics-server", result["name"])
        self.assertEqual(4443, result["port"])

    def test_syntactic_sugar_rmatmul_operator(self):
        # noinspection PyUnresolvedReferences
        result = match(
            sample_k8s_response,
            {
                "containers": Each(
                    {
                        "image": "image" @ _,
                        "name": "name" @ _,
                        "ports": Each({"containerPort": "port" @ _}),
                    }
                )
            },
        )
        self.assertTrue(result)
        self.assertEqual(
            "k8s.gcr.io/metrics-server/metrics-server:v0.4.1", result["image"]
        )
        self.assertEqual("metrics-server", result["name"])
        self.assertEqual(4443, result["port"])

    def test_syntactic_sugar_underscore(self):
        result = match(
            sample_k8s_response,
            {
                "containers": Each(
                    {
                        "image": _ >> "image",
                        "name": _ >> "name",
                        "ports": Each({"containerPort": _ >> "port"}),
                    }
                )
            },
        )
        self.assertTrue(result)
        self.assertEqual(
            "k8s.gcr.io/metrics-server/metrics-server:v0.4.1", result["image"]
        )
        self.assertEqual("metrics-server", result["name"])
        self.assertEqual(4443, result["port"])

    def test_regex_bind_groups(self):
        result = match(
            "abcdef", Regex(r"(?P<one>[a-c]+)(?P<two>[a-z]+)", bind_groups=True)
        )
        self.assertTrue(result)
        self.assertEqual(result["one"], "abc")
        self.assertEqual(result["two"], "def")
        self.assertEqual(result.one, "abc")
        self.assertEqual(result.two, "def")

    def test_nested_capture(self):
        result = match([1, 2, 3, 4], [1, Many(...) >> "x" >> "y", 4])
        self.assertTrue(result)
        self.assertEqual([2, 3], result.x)
        self.assertEqual([2, 3], result.y)


sample_k8s_response = {
    "containers": [
        {
            "args": [
                "--cert-dir=/tmp",
                "--secure-port=4443",
                "--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
                "--kubelet-use-node-status-port",
            ],
            "image": "k8s.gcr.io/metrics-server/metrics-server:v0.4.1",
            "imagePullPolicy": "IfNotPresent",
            "livenessProbe": {
                "failureThreshold": 3,
                "httpGet": {"path": "/livez", "port": "https", "scheme": "HTTPS"},
                "periodSeconds": 10,
                "successThreshold": 1,
                "timeoutSeconds": 1,
            },
            "name": "metrics-server",
            "ports": [{"containerPort": 4443, "name": "https", "protocol": "TCP"}],
            "readinessProbe": {
                "failureThreshold": 3,
                "httpGet": {"path": "/readyz", "port": "https", "scheme": "HTTPS"},
                "periodSeconds": 10,
                "successThreshold": 1,
                "timeoutSeconds": 1,
            },
            "resources": {},
            "securityContext": {
                "readOnlyRootFilesystem": True,
                "runAsNonRoot": True,
                "runAsUser": 1000,
            },
            "terminationMessagePath": "/dev/termination-log",
            "terminationMessagePolicy": "File",
            "volumeMounts": [
                {"mountPath": "/tmp", "name": "tmp-dir"},
                {
                    "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
                    "name": "metrics-server-token-2j86f",
                    "readOnly": True,
                },
            ],
        }
    ],
    "dnsPolicy": "ClusterFirst",
    "enableServiceLinks": True,
    "nodeName": "ip-10-2-169-118.ec2.internal",
    "nodeSelector": {"kubernetes.io/os": "linux"},
    "priority": 2000000000,
    "priorityClassName": "system-cluster-critical",
    "restartPolicy": "Always",
    "schedulerName": "default-scheduler",
    "securityContext": {},
    "serviceAccount": "metrics-server",
    "serviceAccountName": "metrics-server",
    "terminationGracePeriodSeconds": 30,
    "tolerations": [
        {
            "effect": "NoExecute",
            "key": "node.kubernetes.io/not-ready",
            "operator": "Exists",
            "tolerationSeconds": 300,
        },
        {
            "effect": "NoExecute",
            "key": "node.kubernetes.io/unreachable",
            "operator": "Exists",
            "tolerationSeconds": 300,
        },
    ],
    "volumes": [
        {"emptyDir": {}, "name": "tmp-dir"},
        {
            "name": "metrics-server-token-2j86f",
            "secret": {"defaultMode": 420, "secretName": "metrics-server-token-2j86f"},
        },
    ],
}
