"""CampusGateway API endpoints.

This file is automatically @generated from the Meraki API specification.
Do not edit this file manually.

"""

from __future__ import annotations

import urllib.parse
from typing import TYPE_CHECKING, Any, Literal

from meraki_client.schemas import (
    CreateNetworkCampusGatewayClusterDevicesItem,
    CreateNetworkCampusGatewayClusterNameservers,
    CreateNetworkCampusGatewayClusterPortChannelsItem,
    CreateNetworkCampusGatewayClusterResponse,
    CreateNetworkCampusGatewayClusterTunnelsItem,
    CreateNetworkCampusGatewayClusterUplinksItem,
    GetOrganizationCampusGatewayClustersResponseItemsItem,
    GetOrganizationCampusGatewayDevicesUplinksLocalOverridesByDeviceResponseItemsItem,
    UpdateNetworkCampusGatewayClusterDevicesItem,
    UpdateNetworkCampusGatewayClusterNameservers,
    UpdateNetworkCampusGatewayClusterPortChannelsItem,
    UpdateNetworkCampusGatewayClusterResponse,
    UpdateNetworkCampusGatewayClusterTunnelsItem,
    UpdateNetworkCampusGatewayClusterUplinksItem,
)

if TYPE_CHECKING:
    from meraki_client._session import PaginatedResponse, Session


class CampusGateway:
    """CampusGateway class."""

    def __init__(self, session: Session) -> None:
        self._session = session

    def create_network_campus_gateway_cluster(
        self,
        *,
        network_id: str,
        name: str,
        uplinks: list[CreateNetworkCampusGatewayClusterUplinksItem],
        tunnels: list[CreateNetworkCampusGatewayClusterTunnelsItem],
        nameservers: CreateNetworkCampusGatewayClusterNameservers,
        port_channels: list[CreateNetworkCampusGatewayClusterPortChannelsItem],
        devices: list[CreateNetworkCampusGatewayClusterDevicesItem] | None = None,
        notes: str | None = None,
    ) -> CreateNetworkCampusGatewayClusterResponse:
        """Create a cluster and add campus gateways to it.

        [API documentation: createNetworkCampusGatewayCluster](https://developer.cisco.com/meraki/api-v1/#!create-network-campus-gateway-cluster)

        Args:
            network_id: Network ID.
            name: Name of the new cluster.
            uplinks: Uplink interface settings of the cluster.
            tunnels: Tunnel interface settings of the cluster: Reuse uplink or specify tunnel
                interface.
            nameservers: Nameservers of the cluster.
            port_channels: Port channel settings of the cluster.
            devices: Devices to be added to the cluster.
            notes: Notes about cluster with max size of 511 characters allowed.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "clusterId": "1284392014818",
              "name": "North Campus",
              "uplinks": [
                {
                  "interface": "man1",
                  "vlan": 5,
                  "addresses": [
                    {
                      "assignmentMode": "static",
                      "protocol": "ipv4",
                      "gateway": "1.2.3.5",
                      "subnetMask": "255.255.255.0"
                    }
                  ]
                }
              ],
              "tunnels": [
                {
                  "uplink": {
                    "interface": "man1"
                  },
                  "interface": "tun1",
                  "vlan": 6,
                  "addresses": [
                    {
                      "protocol": "ipv4",
                      "gateway": "2.3.5.6",
                      "subnetMask": "255.255.255.0"
                    }
                  ]
                }
              ],
              "nameservers": {
                "addresses": [
                  "8.8.8.8",
                  "8.8.4.4"
                ]
              },
              "portChannels": [
                {
                  "id": "1284392014830",
                  "name": "Port-channel1",
                  "vlan": 25,
                  "allowedVlans": "10-20"
                }
              ],
              "devices": [
                {
                  "serial": "Q234-ABCD-0001",
                  "memberId": "1",
                  "uplinks": [
                    {
                      "interface": "man1",
                      "addresses": [
                        {
                          "protocol": "ipv4",
                          "address": "5.1.2.3"
                        }
                      ]
                    }
                  ],
                  "tunnels": [
                    {
                      "interface": "tun1",
                      "addresses": [
                        {
                          "protocol": "ipv4",
                          "address": "6.2.6.7"
                        }
                      ]
                    }
                  ]
                }
              ],
              "notes": "This cluster is for New York Office",
              "url": "https://n123.meraki.com/networkName/n/abc123/manage/campus_gateways/clusters"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/campusGateway/clusters"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if uplinks is not None:
            payload["uplinks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in uplinks
            ]
        if tunnels is not None:
            payload["tunnels"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in tunnels
            ]
        if nameservers is not None:
            payload["nameservers"] = nameservers.model_dump(by_alias=True, exclude_none=True)
        if port_channels is not None:
            payload["portChannels"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in port_channels
            ]
        if devices is not None:
            payload["devices"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in devices
            ]
        if notes is not None:
            payload["notes"] = notes

        return self._session.post(
            scope="campusGateway",
            operation_id="createNetworkCampusGatewayCluster",
            path=path,
            json=payload,
            response_schema=CreateNetworkCampusGatewayClusterResponse,
        )

    def update_network_campus_gateway_cluster(
        self,
        *,
        network_id: str,
        cluster_id: str,
        name: str | None = None,
        uplinks: list[UpdateNetworkCampusGatewayClusterUplinksItem] | None = None,
        tunnels: list[UpdateNetworkCampusGatewayClusterTunnelsItem] | None = None,
        nameservers: UpdateNetworkCampusGatewayClusterNameservers | None = None,
        port_channels: list[UpdateNetworkCampusGatewayClusterPortChannelsItem] | None = None,
        devices: list[UpdateNetworkCampusGatewayClusterDevicesItem] | None = None,
        notes: str | None = None,
    ) -> UpdateNetworkCampusGatewayClusterResponse:
        """Update a cluster and add/remove campus gateways to/from it.

        [API documentation: updateNetworkCampusGatewayCluster](https://developer.cisco.com/meraki/api-v1/#!update-network-campus-gateway-cluster)

        Args:
            network_id: Network ID.
            cluster_id: Cluster ID.
            name: Name of the cluster.
            uplinks: Uplink interface settings of the cluster.
            tunnels: Tunnel interface settings of the cluster: Reuse uplink or specify tunnel
                interface.
            nameservers: Nameservers of the cluster.
            port_channels: Port channel settings of the cluster.
            devices: Devices in the cluster.
            notes: Notes about cluster with max size of 511 characters allowed.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "clusterId": "1284392014818",
              "name": "North Campus",
              "uplinks": [
                {
                  "interface": "man1",
                  "vlan": 5,
                  "addresses": [
                    {
                      "assignmentMode": "static",
                      "protocol": "ipv4",
                      "gateway": "1.2.3.5",
                      "subnetMask": "255.255.255.0"
                    }
                  ]
                }
              ],
              "tunnels": [
                {
                  "uplink": {
                    "interface": "man1"
                  },
                  "interface": "tun1",
                  "vlan": 6,
                  "addresses": [
                    {
                      "protocol": "ipv4",
                      "gateway": "2.3.5.6",
                      "subnetMask": "255.255.255.0"
                    }
                  ]
                }
              ],
              "nameservers": {
                "addresses": [
                  "8.8.8.8",
                  "8.8.4.4"
                ]
              },
              "portChannels": [
                {
                  "id": "1284392014830",
                  "name": "Port-channel1",
                  "vlan": 25,
                  "allowedVlans": "10-20"
                }
              ],
              "devices": [
                {
                  "serial": "Q234-ABCD-0001",
                  "memberId": "1",
                  "uplinks": [
                    {
                      "interface": "man1",
                      "addresses": [
                        {
                          "protocol": "ipv4",
                          "address": "5.1.2.3"
                        }
                      ]
                    }
                  ],
                  "tunnels": [
                    {
                      "interface": "tun1",
                      "addresses": [
                        {
                          "protocol": "ipv4",
                          "address": "6.2.6.7"
                        }
                      ]
                    }
                  ]
                }
              ],
              "notes": "This cluster is for New York Office",
              "url": "https://n123.meraki.com/networkName/n/abc123/manage/campus_gateways/clusters"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        cluster_id = urllib.parse.quote(str(cluster_id), safe="")
        path = f"/networks/{network_id}/campusGateway/clusters/{cluster_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if uplinks is not None:
            payload["uplinks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in uplinks
            ]
        if tunnels is not None:
            payload["tunnels"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in tunnels
            ]
        if nameservers is not None:
            payload["nameservers"] = nameservers.model_dump(by_alias=True, exclude_none=True)
        if port_channels is not None:
            payload["portChannels"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in port_channels
            ]
        if devices is not None:
            payload["devices"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in devices
            ]
        if notes is not None:
            payload["notes"] = notes

        return self._session.put(
            scope="campusGateway",
            operation_id="updateNetworkCampusGatewayCluster",
            path=path,
            json=payload,
            response_schema=UpdateNetworkCampusGatewayClusterResponse,
        )

    def get_organization_campus_gateway_clusters(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationCampusGatewayClustersResponseItemsItem]:
        """Get the details of campus gateway clusters.

        [API documentation: getOrganizationCampusGatewayClusters](https://developer.cisco.com/meraki/api-v1/#!get-organization-campus-gateway-clusters)

        Args:
            organization_id: Organization ID.
            network_ids: Networks for which information should be gathered.
            per_page: The number of entries per page returned. Acceptable range is 3 - 100. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "network": {
                    "id": "N_2313"
                  },
                  "clusterId": "1284392014818",
                  "name": "North Campus",
                  "uplinks": [
                    {
                      "interface": "man1",
                      "vlan": 5,
                      "addresses": [
                        {
                          "assignmentMode": "static",
                          "protocol": "ipv4",
                          "gateway": "1.2.3.5",
                          "subnetMask": "255.255.255.0"
                        }
                      ]
                    }
                  ],
                  "tunnels": [
                    {
                      "uplink": {
                        "interface": "man1"
                      },
                      "interface": "tun1",
                      "vlan": 6,
                      "addresses": [
                        {
                          "protocol": "ipv4",
                          "gateway": "2.3.5.6",
                          "subnetMask": "255.255.255.0"
                        }
                      ]
                    }
                  ],
                  "nameservers": {
                    "addresses": [
                      "8.8.8.8",
                      "8.8.4.4"
                    ]
                  },
                  "portChannels": [
                    {
                      "id": "1284392014830",
                      "name": "Port-channel1",
                      "vlan": 25,
                      "allowedVlans": "10-20"
                    }
                  ],
                  "devices": [
                    {
                      "serial": "Q234-ABCD-0001",
                      "memberId": "1",
                      "uplinks": [
                        {
                          "interface": "man1",
                          "addresses": [
                            {
                              "protocol": "ipv4",
                              "address": "5.1.2.3"
                            }
                          ]
                        }
                      ],
                      "tunnels": [
                        {
                          "interface": "tun1",
                          "addresses": [
                            {
                              "protocol": "ipv4",
                              "address": "6.2.6.7"
                            }
                          ]
                        }
                      ]
                    }
                  ],
                  "notes": "This cluster is for New York Office",
                  "url": "https://n123.meraki.com/networkName/n/abc123/manage/campus_gateways/clusters"
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 2,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/campusGateway/clusters"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="campusGateway",
            operation_id="getOrganizationCampusGatewayClusters",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationCampusGatewayClustersResponseItemsItem,
        )

    def get_organization_campus_gateway_devices_uplinks_local_overrides_by_device(
        self,
        organization_id: str,
        *,
        serials: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[
        GetOrganizationCampusGatewayDevicesUplinksLocalOverridesByDeviceResponseItemsItem
    ]:
        """Uplink overrides configured locally on Campus Gateway devices in an organization.

        [API documentation: getOrganizationCampusGatewayDevicesUplinksLocalOverridesByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-campus-gateway-devices-uplinks-local-overrides-by-device)

        Args:
            organization_id: Organization ID.
            serials: A list of serial numbers. The returned devices will be filtered to only include
                these serials.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "serial": "Q234-ABCD-0001",
                  "uplink": {
                    "interface": "man1",
                    "vlan": 5,
                    "addresses": [
                      {
                        "assignmentMode": "static",
                        "protocol": "ipv4",
                        "gateway": "1.2.3.5",
                        "subnetMask": "255.255.255.0",
                        "address": "121.12.12.1"
                      }
                    ]
                  },
                  "nameservers": {
                    "addresses": [
                      "8.8.8.8",
                      "8.8.4.4"
                    ]
                  },
                  "sgt": 300
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/campusGateway/devices/uplinks/localOverrides/byDevice"

        params: dict[str, Any] = {}
        if serials is not None:
            params["serials[]"] = serials
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="campusGateway",
            operation_id="getOrganizationCampusGatewayDevicesUplinksLocalOverridesByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationCampusGatewayDevicesUplinksLocalOverridesByDeviceResponseItemsItem,
        )
