"""
FortiOS CMDB - Vpn ipsec phase1_interface

Configuration endpoint for managing cmdb vpn/ipsec/phase1_interface objects.

API Endpoints:
    GET    /cmdb/vpn/ipsec/phase1_interface
    POST   /cmdb/vpn/ipsec/phase1_interface
    PUT    /cmdb/vpn/ipsec/phase1_interface/{identifier}
    DELETE /cmdb/vpn/ipsec/phase1_interface/{identifier}

Example Usage:
    >>> from hfortix_fortios import FortiOS
    >>> fgt = FortiOS(host="192.168.1.99", token="your-api-token")
    >>>
    >>> # List all items
    >>> items = fgt.api.cmdb.vpn_ipsec_phase1_interface.get()
    >>>
    >>> # Create with auto-normalization (strings/lists converted automatically)
    >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.post(
    ...     name="example",
    ...     srcintf="port1",  # Auto-converted to [{'name': 'port1'}]
    ...     dstintf=["port2", "port3"],  # Auto-converted to list of dicts
    ... )

Important:
    - Use **POST** to create new objects
    - Use **PUT** to update existing objects
    - Use **GET** to retrieve configuration
    - Use **DELETE** to remove objects
    - **Auto-normalization**: List fields accept strings or lists, automatically
      converted to FortiOS format [{'name': '...'}]
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Literal, Union

if TYPE_CHECKING:
    from collections.abc import Coroutine
    from hfortix_core.http.interface import IHTTPClient
    from hfortix_fortios.models import FortiObject

# Import helper functions from central _helpers module
from hfortix_fortios._helpers import (
    build_api_payload,
    build_cmdb_payload,  # Keep for backward compatibility / manual usage
    is_success,
    quote_path_param,  # URL encoding for path parameters
    normalize_table_field,  # For table field normalization
)
# Import metadata mixin for schema introspection
from hfortix_fortios._helpers.metadata_mixin import MetadataMixin

# Import Protocol-based type hints (eliminates need for local @overload decorators)
from hfortix_fortios._protocols import CRUDEndpoint

class Phase1Interface(CRUDEndpoint, MetadataMixin):
    """Phase1Interface Operations."""
    
    # Configure metadata mixin to use this endpoint's helper module
    _helper_module_name = "phase1_interface"
    
    # ========================================================================
    # Table Fields Metadata (for normalization)
    # Auto-generated from schema - supports flexible input formats
    # ========================================================================
    _TABLE_FIELDS = {
        "certificate": {
            "mkey": "name",
            "required_fields": ['name'],
            "example": "[{'name': 'value'}]",
        },
        "monitor": {
            "mkey": "name",
            "required_fields": ['name'],
            "example": "[{'name': 'value'}]",
        },
        "internal_domain_list": {
            "mkey": "domain-name",
            "required_fields": ['domain-name'],
            "example": "[{'domain-name': 'value'}]",
        },
        "dns_suffix_search": {
            "mkey": "dns-suffix",
            "required_fields": ['dns-suffix'],
            "example": "[{'dns-suffix': 'value'}]",
        },
        "ipv4_exclude_range": {
            "mkey": "id",
            "required_fields": ['id', 'start-ip', 'end-ip'],
            "example": "[{'id': 1, 'start-ip': '192.168.1.10', 'end-ip': '192.168.1.10'}]",
        },
        "ipv6_exclude_range": {
            "mkey": "id",
            "required_fields": ['id', 'start-ip', 'end-ip'],
            "example": "[{'id': 1, 'start-ip': 'value', 'end-ip': 'value'}]",
        },
        "backup_gateway": {
            "mkey": "address",
            "required_fields": ['address'],
            "example": "[{'address': 'value'}]",
        },
        "remote_gw_ztna_tags": {
            "mkey": "name",
            "required_fields": ['name'],
            "example": "[{'name': 'value'}]",
        },
    }
    
    # ========================================================================
    # Capabilities (from schema metadata)
    # ========================================================================
    SUPPORTS_CREATE = True
    SUPPORTS_READ = True
    SUPPORTS_UPDATE = True
    SUPPORTS_DELETE = True
    SUPPORTS_MOVE = True
    SUPPORTS_CLONE = True
    SUPPORTS_FILTERING = True
    SUPPORTS_PAGINATION = True
    SUPPORTS_SEARCH = False
    SUPPORTS_SORTING = False

    def __init__(self, client: "IHTTPClient"):
        """Initialize Phase1Interface endpoint."""
        self._client = client

    # ========================================================================
    # GET Method
    # Type hints provided by CRUDEndpoint protocol (no local @overload needed)
    # ========================================================================
    
    def get(
        self,
        name: str | None = None,
        filter: list[str] | None = None,
        count: int | None = None,
        start: int | None = None,
        payload_dict: dict[str, Any] | None = None,
        vdom: str | bool | None = None,
        error_mode: Literal["raise", "return", "print"] | None = None,
        error_format: Literal["detailed", "simple", "code_only"] | None = None,
    ):  # type: ignore[no-untyped-def]
        """
        Retrieve vpn/ipsec/phase1_interface configuration.

        Configure VPN remote gateway.

        Args:
            name: String identifier to retrieve specific object.
                If None, returns all objects.
            filter: List of filter expressions to limit results.
                Each filter uses format: "field==value" or "field!=value"
                Operators: ==, !=, =@ (contains), !@ (not contains), <=, <, >=, >
                Multiple filters use AND logic. For OR, use comma in single string.
                Example: ["name==test", "status==enable"] or ["name==test,name==prod"]
            count: Maximum number of entries to return (pagination).
            start: Starting entry index for pagination (0-based).
            payload_dict: Additional query parameters for advanced options:
                - datasource (bool): Include datasource information
                - with_meta (bool): Include metadata about each object
                - with_contents_hash (bool): Include checksum of object contents
                - format (list[str]): Property names to include (e.g., ["policyid", "srcintf"])
                - scope (str): Query scope - "global", "vdom", or "both"
                - action (str): Special actions - "schema", "default"
                See FortiOS REST API documentation for complete list.
            vdom: Virtual domain name. Use True for global, string for specific VDOM, None for default.
            error_mode: Override client-level error_mode. "raise" raises exceptions, "return" returns error dict, "print" prints errors.
            error_format: Override client-level error_format. "detailed" provides full context, "simple" is concise, "code_only" returns just status code.

        Returns:
            FortiObject instance or list of FortiObject instances. Returns Coroutine if using async client.
            Use .dict, .json, or .raw properties to access as dictionary.
            
            Response structure:
                - http_method: GET
                - results: Configuration object(s)
                - vdom: Virtual domain
                - path: API path
                - name: Object name (single object queries)
                - status: success/error
                - http_status: HTTP status code
                - build: FortiOS build number

        Examples:
            >>> # Get all vpn/ipsec/phase1_interface objects
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.get()
            >>> print(f"Found {len(result['results'])} objects")
            
            >>> # Get specific vpn/ipsec/phase1_interface by name
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.get(name=1)
            >>> print(result['results'])
            
            >>> # Get with filter
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.get(
            ...     filter=["name==test", "status==enable"]
            ... )
            
            >>> # Get with pagination
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.get(
            ...     start=0, count=100
            ... )
            
            >>> # Get schema information  
            >>> schema = fgt.api.cmdb.vpn_ipsec_phase1_interface.get_schema()

        See Also:
            - post(): Create new vpn/ipsec/phase1_interface object
            - put(): Update existing vpn/ipsec/phase1_interface object
            - delete(): Remove vpn/ipsec/phase1_interface object
            - exists(): Check if object exists
            - get_schema(): Get endpoint schema/metadata
        """
        params = payload_dict.copy() if payload_dict else {}
        
        # Add explicit query parameters
        if filter is not None:
            params["filter"] = filter
        if count is not None:
            params["count"] = count
        if start is not None:
            params["start"] = start
        
        if name:
            endpoint = "/vpn.ipsec/phase1-interface/" + quote_path_param(name)
            unwrap_single = True
        else:
            endpoint = "/vpn.ipsec/phase1-interface"
            unwrap_single = False
        
        return self._client.get(
            "cmdb", endpoint, params=params, vdom=vdom, unwrap_single=unwrap_single
        )

    def get_schema(
        self,
        vdom: str | None = None,
        format: str = "schema",
    ) -> Union[dict[str, Any], Coroutine[Any, Any, dict[str, Any]]]:
        """
        Get schema/metadata for this endpoint.
        
        Returns the FortiOS schema definition including available fields,
        their types, required vs optional properties, enum values, nested
        structures, and default values.
        
        This queries the live firewall for its current schema, which may
        vary between FortiOS versions.
        
        Args:
            vdom: Virtual domain. None uses default VDOM.
            format: Schema format - "schema" (FortiOS native) or "json-schema" (JSON Schema standard).
                Defaults to "schema".
                
        Returns:
            Schema definition as dict. Returns Coroutine if using async client.
            
        Example:
            >>> # Get FortiOS native schema
            >>> schema = fgt.api.cmdb.vpn_ipsec_phase1_interface.get_schema()
            >>> print(schema['results'])
            
            >>> # Get JSON Schema format (if supported)
            >>> json_schema = fgt.api.cmdb.vpn_ipsec_phase1_interface.get_schema(format="json-schema")
        
        Note:
            Not all endpoints support all schema formats. The "schema" format
            is most widely supported.
        """
        return self.get(action=format, vdom=vdom)


    # ========================================================================
    # PUT Method
    # Type hints provided by CRUDEndpoint protocol (no local @overload needed)
    # ========================================================================
    
    def put(
        self,
        payload_dict: dict[str, Any] | None = None,
        name: str | None = None,
        type: Literal["static", "dynamic", "ddns"] | None = None,
        interface: str | None = None,
        ip_version: Literal["4", "6"] | None = None,
        ike_version: Literal["1", "2"] | None = None,
        local_gw: str | None = None,
        local_gw6: str | None = None,
        remote_gw: str | None = None,
        remote_gw6: str | None = None,
        remotegw_ddns: str | None = None,
        keylife: int | None = None,
        certificate: str | list[str] | list[dict[str, Any]] | None = None,
        authmethod: Literal["psk", "signature"] | None = None,
        authmethod_remote: Literal["psk", "signature"] | None = None,
        mode: Literal["aggressive", "main"] | None = None,
        peertype: Literal["any", "one", "dialup", "peer", "peergrp"] | None = None,
        peerid: str | None = None,
        default_gw: str | None = None,
        default_gw_priority: int | None = None,
        usrgrp: str | None = None,
        peer: str | None = None,
        peergrp: str | None = None,
        monitor: str | list[str] | list[dict[str, Any]] | None = None,
        monitor_min: int | None = None,
        monitor_hold_down_type: Literal["immediate", "delay", "time"] | None = None,
        monitor_hold_down_delay: int | None = None,
        monitor_hold_down_weekday: Literal["everyday", "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"] | None = None,
        monitor_hold_down_time: str | None = None,
        net_device: Literal["enable", "disable"] | None = None,
        passive_mode: Literal["enable", "disable"] | None = None,
        exchange_interface_ip: Literal["enable", "disable"] | None = None,
        exchange_ip_addr4: str | None = None,
        exchange_ip_addr6: str | None = None,
        aggregate_member: Literal["enable", "disable"] | None = None,
        aggregate_weight: int | None = None,
        packet_redistribution: Literal["enable", "disable"] | None = None,
        peer_egress_shaping: Literal["enable", "disable"] | None = None,
        peer_egress_shaping_value: int | None = None,
        mode_cfg: Literal["disable", "enable"] | None = None,
        mode_cfg_allow_client_selector: Literal["disable", "enable"] | None = None,
        assign_ip: Literal["disable", "enable"] | None = None,
        assign_ip_from: Literal["range", "usrgrp", "dhcp", "name"] | None = None,
        ipv4_start_ip: str | None = None,
        ipv4_end_ip: str | None = None,
        ipv4_netmask: str | None = None,
        dhcp_ra_giaddr: str | None = None,
        dhcp6_ra_linkaddr: str | None = None,
        dns_mode: Literal["manual", "auto"] | None = None,
        ipv4_dns_server1: str | None = None,
        ipv4_dns_server2: str | None = None,
        ipv4_dns_server3: str | None = None,
        internal_domain_list: str | list[str] | list[dict[str, Any]] | None = None,
        dns_suffix_search: str | list[str] | list[dict[str, Any]] | None = None,
        ipv4_wins_server1: str | None = None,
        ipv4_wins_server2: str | None = None,
        ipv4_exclude_range: str | list[str] | list[dict[str, Any]] | None = None,
        ipv4_split_include: str | None = None,
        split_include_service: str | None = None,
        ipv4_name: str | None = None,
        ipv6_start_ip: str | None = None,
        ipv6_end_ip: str | None = None,
        ipv6_prefix: int | None = None,
        ipv6_dns_server1: str | None = None,
        ipv6_dns_server2: str | None = None,
        ipv6_dns_server3: str | None = None,
        ipv6_exclude_range: str | list[str] | list[dict[str, Any]] | None = None,
        ipv6_split_include: str | None = None,
        ipv6_name: str | None = None,
        ip_delay_interval: int | None = None,
        unity_support: Literal["disable", "enable"] | None = None,
        domain: str | None = None,
        banner: str | None = None,
        include_local_lan: Literal["disable", "enable"] | None = None,
        ipv4_split_exclude: str | None = None,
        ipv6_split_exclude: str | None = None,
        save_password: Literal["disable", "enable"] | None = None,
        client_auto_negotiate: Literal["disable", "enable"] | None = None,
        client_keep_alive: Literal["disable", "enable"] | None = None,
        backup_gateway: str | list[str] | list[dict[str, Any]] | None = None,
        proposal: Literal["des-md5", "des-sha1", "des-sha256", "des-sha384", "des-sha512", "3des-md5", "3des-sha1", "3des-sha256", "3des-sha384", "3des-sha512", "aes128-md5", "aes128-sha1", "aes128-sha256", "aes128-sha384", "aes128-sha512", "aes128gcm-prfsha1", "aes128gcm-prfsha256", "aes128gcm-prfsha384", "aes128gcm-prfsha512", "aes192-md5", "aes192-sha1", "aes192-sha256", "aes192-sha384", "aes192-sha512", "aes256-md5", "aes256-sha1", "aes256-sha256", "aes256-sha384", "aes256-sha512", "aes256gcm-prfsha1", "aes256gcm-prfsha256", "aes256gcm-prfsha384", "aes256gcm-prfsha512", "chacha20poly1305-prfsha1", "chacha20poly1305-prfsha256", "chacha20poly1305-prfsha384", "chacha20poly1305-prfsha512", "aria128-md5", "aria128-sha1", "aria128-sha256", "aria128-sha384", "aria128-sha512", "aria192-md5", "aria192-sha1", "aria192-sha256", "aria192-sha384", "aria192-sha512", "aria256-md5", "aria256-sha1", "aria256-sha256", "aria256-sha384", "aria256-sha512", "seed-md5", "seed-sha1", "seed-sha256", "seed-sha384", "seed-sha512"] | list[str] | None = None,
        add_route: Literal["disable", "enable"] | None = None,
        add_gw_route: Literal["enable", "disable"] | None = None,
        psksecret: Any | None = None,
        psksecret_remote: Any | None = None,
        keepalive: int | None = None,
        distance: int | None = None,
        priority: int | None = None,
        localid: str | None = None,
        localid_type: Literal["auto", "fqdn", "user-fqdn", "keyid", "address", "asn1dn"] | None = None,
        auto_negotiate: Literal["enable", "disable"] | None = None,
        negotiate_timeout: int | None = None,
        fragmentation: Literal["enable", "disable"] | None = None,
        ip_fragmentation: Literal["pre-encapsulation", "post-encapsulation"] | None = None,
        dpd: Literal["disable", "on-idle", "on-demand"] | None = None,
        dpd_retrycount: int | None = None,
        dpd_retryinterval: str | None = None,
        comments: str | None = None,
        npu_offload: Literal["enable", "disable"] | None = None,
        send_cert_chain: Literal["enable", "disable"] | None = None,
        dhgrp: Literal["1", "2", "5", "14", "15", "16", "17", "18", "19", "20", "21", "27", "28", "29", "30", "31", "32"] | list[str] | None = None,
        addke1: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke2: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke3: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke4: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke5: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke6: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke7: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        suite_b: Literal["disable", "suite-b-gcm-128", "suite-b-gcm-256"] | None = None,
        eap: Literal["enable", "disable"] | None = None,
        eap_identity: Literal["use-id-payload", "send-request"] | None = None,
        eap_exclude_peergrp: str | None = None,
        eap_cert_auth: Literal["enable", "disable"] | None = None,
        acct_verify: Literal["enable", "disable"] | None = None,
        ppk: Literal["disable", "allow", "require"] | None = None,
        ppk_secret: Any | None = None,
        ppk_identity: str | None = None,
        wizard_type: Literal["custom", "dialup-forticlient", "dialup-ios", "dialup-android", "dialup-windows", "dialup-cisco", "static-fortigate", "dialup-fortigate", "static-cisco", "dialup-cisco-fw", "simplified-static-fortigate", "hub-fortigate-auto-discovery", "spoke-fortigate-auto-discovery", "fabric-overlay-orchestrator"] | None = None,
        xauthtype: Literal["disable", "client", "pap", "chap", "auto"] | None = None,
        reauth: Literal["disable", "enable"] | None = None,
        authusr: str | None = None,
        authpasswd: Any | None = None,
        group_authentication: Literal["enable", "disable"] | None = None,
        group_authentication_secret: Any | None = None,
        authusrgrp: str | None = None,
        mesh_selector_type: Literal["disable", "subnet", "host"] | None = None,
        idle_timeout: Literal["enable", "disable"] | None = None,
        shared_idle_timeout: Literal["enable", "disable"] | None = None,
        idle_timeoutinterval: int | None = None,
        ha_sync_esp_seqno: Literal["enable", "disable"] | None = None,
        fgsp_sync: Literal["enable", "disable"] | None = None,
        inbound_dscp_copy: Literal["enable", "disable"] | None = None,
        auto_discovery_sender: Literal["enable", "disable"] | None = None,
        auto_discovery_receiver: Literal["enable", "disable"] | None = None,
        auto_discovery_forwarder: Literal["enable", "disable"] | None = None,
        auto_discovery_psk: Literal["enable", "disable"] | None = None,
        auto_discovery_shortcuts: Literal["independent", "dependent"] | None = None,
        auto_discovery_crossover: Literal["allow", "block"] | None = None,
        auto_discovery_offer_interval: int | None = None,
        auto_discovery_dialup_placeholder: Literal["disable", "enable"] | None = None,
        encapsulation: Literal["none", "gre", "vxlan", "vpn-id-ipip"] | None = None,
        encapsulation_address: Literal["ike", "ipv4", "ipv6"] | None = None,
        encap_local_gw4: str | None = None,
        encap_local_gw6: str | None = None,
        encap_remote_gw4: str | None = None,
        encap_remote_gw6: str | None = None,
        vni: int | None = None,
        nattraversal: Literal["enable", "disable", "forced"] | None = None,
        esn: Literal["require", "allow", "disable"] | None = None,
        fragmentation_mtu: int | None = None,
        childless_ike: Literal["enable", "disable"] | None = None,
        azure_ad_autoconnect: Literal["enable", "disable"] | None = None,
        client_resume: Literal["enable", "disable"] | None = None,
        client_resume_interval: int | None = None,
        rekey: Literal["enable", "disable"] | None = None,
        digital_signature_auth: Literal["enable", "disable"] | None = None,
        signature_hash_alg: Literal["sha1", "sha2-256", "sha2-384", "sha2-512"] | list[str] | None = None,
        rsa_signature_format: Literal["pkcs1", "pss"] | None = None,
        rsa_signature_hash_override: Literal["enable", "disable"] | None = None,
        enforce_unique_id: Literal["disable", "keep-new", "keep-old"] | None = None,
        cert_id_validation: Literal["enable", "disable"] | None = None,
        fec_egress: Literal["enable", "disable"] | None = None,
        fec_send_timeout: int | None = None,
        fec_base: int | None = None,
        fec_codec: Literal["rs", "xor"] | None = None,
        fec_redundant: int | None = None,
        fec_ingress: Literal["enable", "disable"] | None = None,
        fec_receive_timeout: int | None = None,
        fec_health_check: str | None = None,
        fec_mapping_profile: str | None = None,
        network_overlay: Literal["disable", "enable"] | None = None,
        network_id: int | None = None,
        dev_id_notification: Literal["disable", "enable"] | None = None,
        dev_id: str | None = None,
        loopback_asymroute: Literal["enable", "disable"] | None = None,
        link_cost: int | None = None,
        kms: str | None = None,
        exchange_fgt_device_id: Literal["enable", "disable"] | None = None,
        ipv6_auto_linklocal: Literal["enable", "disable"] | None = None,
        ems_sn_check: Literal["enable", "disable"] | None = None,
        cert_trust_store: Literal["local", "ems"] | None = None,
        qkd: Literal["disable", "allow", "require"] | None = None,
        qkd_hybrid: Literal["disable", "allow", "require"] | None = None,
        qkd_profile: str | None = None,
        transport: Literal["udp", "auto", "tcp"] | None = None,
        fortinet_esp: Literal["enable", "disable"] | None = None,
        auto_transport_threshold: int | None = None,
        remote_gw_match: Literal["any", "ipmask", "iprange", "geography", "ztna"] | None = None,
        remote_gw_subnet: Any | None = None,
        remote_gw_start_ip: str | None = None,
        remote_gw_end_ip: str | None = None,
        remote_gw_country: str | None = None,
        remote_gw_ztna_tags: str | list[str] | list[dict[str, Any]] | None = None,
        remote_gw6_match: Literal["any", "ipprefix", "iprange", "geography"] | None = None,
        remote_gw6_subnet: str | None = None,
        remote_gw6_start_ip: str | None = None,
        remote_gw6_end_ip: str | None = None,
        remote_gw6_country: str | None = None,
        cert_peer_username_validation: Literal["none", "othername", "rfc822name", "cn"] | None = None,
        cert_peer_username_strip: Literal["disable", "enable"] | None = None,
        q_action: Literal["move"] | None = None,
        q_before: str | None = None,
        q_after: str | None = None,
        q_scope: str | None = None,
        vdom: str | bool | None = None,
        error_mode: Literal["raise", "return", "print"] | None = None,
        error_format: Literal["detailed", "simple", "code_only"] | None = None,
    ):  # type: ignore[no-untyped-def]
        """
        Update existing vpn/ipsec/phase1_interface object.

        Configure VPN remote gateway.

        Args:
            payload_dict: Object data as dict. Must include name (primary key).
            name: IPsec remote gateway name.
            type: Remote gateway type.
            interface: Local physical, aggregate, or VLAN outgoing interface.
            ip_version: IP version to use for VPN interface.
            ike_version: IKE protocol version.
            local_gw: IPv4 address of the local gateway's external interface.
            local_gw6: IPv6 address of the local gateway's external interface.
            remote_gw: IPv4 address of the remote gateway's external interface.
            remote_gw6: IPv6 address of the remote gateway's external interface.
            remotegw_ddns: Domain name of remote gateway. For example, name.ddns.com.
            keylife: Time to wait in seconds before phase 1 encryption key expires.
            certificate: The names of up to 4 signed personal certificates.
                Default format: [{'name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'name': 'val1'}, ...]
                  - List of dicts: [{'name': 'value'}] (recommended)
            authmethod: Authentication method.
            authmethod_remote: Authentication method (remote side).
            mode: The ID protection mode used to establish a secure channel.
            peertype: Accept this peer type.
            peerid: Accept this peer identity.
            default_gw: IPv4 address of default route gateway to use for traffic exiting the interface.
            default_gw_priority: Priority for default gateway route. A higher priority number signifies a less preferred route.
            usrgrp: User group name for dialup peers.
            peer: Accept this peer certificate.
            peergrp: Accept this peer certificate group.
            monitor: IPsec interface as backup for primary interface.
                Default format: [{'name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'name': 'val1'}, ...]
                  - List of dicts: [{'name': 'value'}] (recommended)
            monitor_min: Minimum number of links to become degraded before activating this interface.  Zero (0) means all links must be down before activating this interface.
            monitor_hold_down_type: Recovery time method when primary interface re-establishes.
            monitor_hold_down_delay: Time to wait in seconds before recovery once primary re-establishes.
            monitor_hold_down_weekday: Day of the week to recover once primary re-establishes.
            monitor_hold_down_time: Time of day at which to fail back to primary after it re-establishes.
            net_device: Enable/disable kernel device creation.
            passive_mode: Enable/disable IPsec passive mode for static tunnels.
            exchange_interface_ip: Enable/disable exchange of IPsec interface IP address.
            exchange_ip_addr4: IPv4 address to exchange with peers.
            exchange_ip_addr6: IPv6 address to exchange with peers.
            aggregate_member: Enable/disable use as an aggregate member.
            aggregate_weight: Link weight for aggregate.
            packet_redistribution: Enable/disable packet distribution (RPS) on the IPsec interface.
            peer_egress_shaping: Enable/disable peer egress shaping.
            peer_egress_shaping_value: Configure outbound bandwidth to use for peer egress shaping in kbps (0 - 80000000, default = 0).
            mode_cfg: Enable/disable configuration method.
            mode_cfg_allow_client_selector: Enable/disable mode-cfg client to use custom phase2 selectors.
            assign_ip: Enable/disable assignment of IP to IPsec interface via configuration method.
            assign_ip_from: Method by which the IP address will be assigned.
            ipv4_start_ip: Start of IPv4 range.
            ipv4_end_ip: End of IPv4 range.
            ipv4_netmask: IPv4 Netmask.
            dhcp_ra_giaddr: Relay agent gateway IP address to use in the giaddr field of DHCP requests.
            dhcp6_ra_linkaddr: Relay agent IPv6 link address to use in DHCP6 requests.
            dns_mode: DNS server mode.
            ipv4_dns_server1: IPv4 DNS server 1.
            ipv4_dns_server2: IPv4 DNS server 2.
            ipv4_dns_server3: IPv4 DNS server 3.
            internal_domain_list: One or more internal domain names in quotes separated by spaces.
                Default format: [{'domain-name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'domain-name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'domain-name': 'val1'}, ...]
                  - List of dicts: [{'domain-name': 'value'}] (recommended)
            dns_suffix_search: One or more DNS domain name suffixes in quotes separated by spaces.
                Default format: [{'dns-suffix': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'dns-suffix': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'dns-suffix': 'val1'}, ...]
                  - List of dicts: [{'dns-suffix': 'value'}] (recommended)
            ipv4_wins_server1: WINS server 1.
            ipv4_wins_server2: WINS server 2.
            ipv4_exclude_range: Configuration Method IPv4 exclude ranges.
                Default format: [{'id': 1, 'start-ip': '192.168.1.10', 'end-ip': '192.168.1.10'}]
                Required format: List of dicts with keys: id, start-ip, end-ip
                  (String format not allowed due to multiple required fields)
            ipv4_split_include: IPv4 split-include subnets.
            split_include_service: Split-include services.
            ipv4_name: IPv4 address name.
            ipv6_start_ip: Start of IPv6 range.
            ipv6_end_ip: End of IPv6 range.
            ipv6_prefix: IPv6 prefix.
            ipv6_dns_server1: IPv6 DNS server 1.
            ipv6_dns_server2: IPv6 DNS server 2.
            ipv6_dns_server3: IPv6 DNS server 3.
            ipv6_exclude_range: Configuration method IPv6 exclude ranges.
                Default format: [{'id': 1, 'start-ip': 'value', 'end-ip': 'value'}]
                Required format: List of dicts with keys: id, start-ip, end-ip
                  (String format not allowed due to multiple required fields)
            ipv6_split_include: IPv6 split-include subnets.
            ipv6_name: IPv6 address name.
            ip_delay_interval: IP address reuse delay interval in seconds (0 - 28800).
            unity_support: Enable/disable support for Cisco UNITY Configuration Method extensions.
            domain: Instruct unity clients about the single default DNS domain.
            banner: Message that unity client should display after connecting.
            include_local_lan: Enable/disable allow local LAN access on unity clients.
            ipv4_split_exclude: IPv4 subnets that should not be sent over the IPsec tunnel.
            ipv6_split_exclude: IPv6 subnets that should not be sent over the IPsec tunnel.
            save_password: Enable/disable saving XAuth username and password on VPN clients.
            client_auto_negotiate: Enable/disable allowing the VPN client to bring up the tunnel when there is no traffic.
            client_keep_alive: Enable/disable allowing the VPN client to keep the tunnel up when there is no traffic.
            backup_gateway: Instruct unity clients about the backup gateway address(es).
                Default format: [{'address': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'address': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'address': 'val1'}, ...]
                  - List of dicts: [{'address': 'value'}] (recommended)
            proposal: Phase1 proposal.
            add_route: Enable/disable control addition of a route to peer destination selector.
            add_gw_route: Enable/disable automatically add a route to the remote gateway.
            psksecret: Pre-shared secret for PSK authentication (ASCII string or hexadecimal encoded with a leading 0x).
            psksecret_remote: Pre-shared secret for remote side PSK authentication (ASCII string or hexadecimal encoded with a leading 0x).
            keepalive: NAT-T keep alive interval.
            distance: Distance for routes added by IKE (1 - 255).
            priority: Priority for routes added by IKE (1 - 65535).
            localid: Local ID.
            localid_type: Local ID type.
            auto_negotiate: Enable/disable automatic initiation of IKE SA negotiation.
            negotiate_timeout: IKE SA negotiation timeout in seconds (1 - 300).
            fragmentation: Enable/disable fragment IKE message on re-transmission.
            ip_fragmentation: Determine whether IP packets are fragmented before or after IPsec encapsulation.
            dpd: Dead Peer Detection mode.
            dpd_retrycount: Number of DPD retry attempts.
            dpd_retryinterval: DPD retry interval.
            comments: Comment.
            npu_offload: Enable/disable offloading NPU.
            send_cert_chain: Enable/disable sending certificate chain.
            dhgrp: DH group.
            addke1: ADDKE1 group.
            addke2: ADDKE2 group.
            addke3: ADDKE3 group.
            addke4: ADDKE4 group.
            addke5: ADDKE5 group.
            addke6: ADDKE6 group.
            addke7: ADDKE7 group.
            suite_b: Use Suite-B.
            eap: Enable/disable IKEv2 EAP authentication.
            eap_identity: IKEv2 EAP peer identity type.
            eap_exclude_peergrp: Peer group excluded from EAP authentication.
            eap_cert_auth: Enable/disable peer certificate authentication in addition to EAP if peer is a FortiClient endpoint.
            acct_verify: Enable/disable verification of RADIUS accounting record.
            ppk: Enable/disable IKEv2 Postquantum Preshared Key (PPK).
            ppk_secret: IKEv2 Postquantum Preshared Key (ASCII string or hexadecimal encoded with a leading 0x).
            ppk_identity: IKEv2 Postquantum Preshared Key Identity.
            wizard_type: GUI VPN Wizard Type.
            xauthtype: XAuth type.
            reauth: Enable/disable re-authentication upon IKE SA lifetime expiration.
            authusr: XAuth user name.
            authpasswd: XAuth password (max 35 characters).
            group_authentication: Enable/disable IKEv2 IDi group authentication.
            group_authentication_secret: Password for IKEv2 ID group authentication. ASCII string or hexadecimal indicated by a leading 0x.
            authusrgrp: Authentication user group.
            mesh_selector_type: Add selectors containing subsets of the configuration depending on traffic.
            idle_timeout: Enable/disable IPsec tunnel idle timeout.
            shared_idle_timeout: Enable/disable IPsec tunnel shared idle timeout.
            idle_timeoutinterval: IPsec tunnel idle timeout in minutes (5 - 43200).
            ha_sync_esp_seqno: Enable/disable sequence number jump ahead for IPsec HA.
            fgsp_sync: Enable/disable IPsec syncing of tunnels for FGSP IPsec.
            inbound_dscp_copy: Enable/disable copy the dscp in the ESP header to the inner IP Header.
            auto_discovery_sender: Enable/disable sending auto-discovery short-cut messages.
            auto_discovery_receiver: Enable/disable accepting auto-discovery short-cut messages.
            auto_discovery_forwarder: Enable/disable forwarding auto-discovery short-cut messages.
            auto_discovery_psk: Enable/disable use of pre-shared secrets for authentication of auto-discovery tunnels.
            auto_discovery_shortcuts: Control deletion of child short-cut tunnels when the parent tunnel goes down.
            auto_discovery_crossover: Allow/block set-up of short-cut tunnels between different network IDs.
            auto_discovery_offer_interval: Interval between shortcut offer messages in seconds (1 - 300, default = 5).
            auto_discovery_dialup_placeholder: Control if this dynamic gateway is used for shortcut connections only.
            encapsulation: Enable/disable GRE/VXLAN/VPNID encapsulation.
            encapsulation_address: Source for GRE/VXLAN tunnel address.
            encap_local_gw4: Local IPv4 address of GRE/VXLAN tunnel.
            encap_local_gw6: Local IPv6 address of GRE/VXLAN tunnel.
            encap_remote_gw4: Remote IPv4 address of GRE/VXLAN tunnel.
            encap_remote_gw6: Remote IPv6 address of GRE/VXLAN tunnel.
            vni: VNI of VXLAN tunnel.
            nattraversal: Enable/disable NAT traversal.
            esn: Extended sequence number (ESN) negotiation.
            fragmentation_mtu: IKE fragmentation MTU (500 - 16000).
            childless_ike: Enable/disable childless IKEv2 initiation (RFC 6023).
            azure_ad_autoconnect: Enable/disable Azure AD Auto-Connect for FortiClient.
            client_resume: Enable/disable resumption of offline FortiClient sessions.  When a FortiClient enabled laptop is closed or enters sleep/hibernate mode, enabling this feature allows FortiClient to keep the tunnel during this period, and allows users to immediately resume using the IPsec tunnel when the device wakes up.
            client_resume_interval: Maximum time in seconds during which a VPN client may resume using a tunnel after a client PC has entered sleep mode or temporarily lost its network connection (120 - 172800, default = 7200).
            rekey: Enable/disable phase1 rekey.
            digital_signature_auth: Enable/disable IKEv2 Digital Signature Authentication (RFC 7427).
            signature_hash_alg: Digital Signature Authentication hash algorithms.
            rsa_signature_format: Digital Signature Authentication RSA signature format.
            rsa_signature_hash_override: Enable/disable IKEv2 RSA signature hash algorithm override.
            enforce_unique_id: Enable/disable peer ID uniqueness check.
            cert_id_validation: Enable/disable cross validation of peer ID and the identity in the peer's certificate as specified in RFC 4945.
            fec_egress: Enable/disable Forward Error Correction for egress IPsec traffic.
            fec_send_timeout: Timeout in milliseconds before sending Forward Error Correction packets (1 - 1000).
            fec_base: Number of base Forward Error Correction packets (1 - 20).
            fec_codec: Forward Error Correction encoding/decoding algorithm.
            fec_redundant: Number of redundant Forward Error Correction packets (1 - 5 for reed-solomon, 1 for xor).
            fec_ingress: Enable/disable Forward Error Correction for ingress IPsec traffic.
            fec_receive_timeout: Timeout in milliseconds before dropping Forward Error Correction packets (1 - 1000).
            fec_health_check: SD-WAN health check.
            fec_mapping_profile: Forward Error Correction (FEC) mapping profile.
            network_overlay: Enable/disable network overlays.
            network_id: VPN gateway network ID.
            dev_id_notification: Enable/disable device ID notification.
            dev_id: Device ID carried by the device ID notification.
            loopback_asymroute: Enable/disable asymmetric routing for IKE traffic on loopback interface.
            link_cost: VPN tunnel underlay link cost.
            kms: Key Management Services server.
            exchange_fgt_device_id: Enable/disable device identifier exchange with peer FortiGate units for use of VPN monitor data by FortiManager.
            ipv6_auto_linklocal: Enable/disable auto generation of IPv6 link-local address using last 8 bytes of mode-cfg assigned IPv6 address.
            ems_sn_check: Enable/disable verification of EMS serial number.
            cert_trust_store: CA certificate trust store.
            qkd: Enable/disable use of Quantum Key Distribution (QKD) server.
            qkd_hybrid: Enable/disable use of Quantum Key Distribution (QKD) hybrid keys.
            qkd_profile: Quantum Key Distribution (QKD) server profile.
            transport: Set IKE transport protocol.
            fortinet_esp: Enable/disable Fortinet ESP encapsulation.
            auto_transport_threshold: Timeout in seconds before falling back to next transport protocol.
            remote_gw_match: Set type of IPv4 remote gateway address matching.
            remote_gw_subnet: IPv4 address and subnet mask.
            remote_gw_start_ip: First IPv4 address in the range.
            remote_gw_end_ip: Last IPv4 address in the range.
            remote_gw_country: IPv4 addresses associated to a specific country.
            remote_gw_ztna_tags: IPv4 ZTNA posture tags.
                Default format: [{'name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'name': 'val1'}, ...]
                  - List of dicts: [{'name': 'value'}] (recommended)
            remote_gw6_match: Set type of IPv6 remote gateway address matching.
            remote_gw6_subnet: IPv6 address and prefix.
            remote_gw6_start_ip: First IPv6 address in the range.
            remote_gw6_end_ip: Last IPv6 address in the range.
            remote_gw6_country: IPv6 addresses associated to a specific country.
            cert_peer_username_validation: Enable/disable cross validation of peer username and the identity in the peer's certificate.
            cert_peer_username_strip: Enable/disable domain stripping on certificate identity.
            vdom: Virtual domain name.
            error_mode: Override client-level error_mode. "raise" raises exceptions, "return" returns error dict, "print" prints errors.
            error_format: Override client-level error_format. "detailed" provides full context, "simple" is concise, "code_only" returns just status code.

        Returns:
            FortiObject instance. Use .dict, .json, or .raw to access as dictionary.

        Raises:
            ValueError: If name is missing from payload

        Examples:
            >>> # Update specific fields
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.put(
            ...     name=1,
            ...     # ... fields to update
            ... )
            
            >>> # Update using payload dict
            >>> payload = {
            ...     "name": 1,
            ...     "field1": "new-value",
            ... }
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.put(payload_dict=payload)

        See Also:
            - post(): Create new object
            - set(): Intelligent create or update
        """
        # Apply normalization for table fields (supports flexible input formats)
        if certificate is not None:
            certificate = normalize_table_field(
                certificate,
                mkey="name",
                required_fields=['name'],
                field_name="certificate",
                example="[{'name': 'value'}]",
            )
        if monitor is not None:
            monitor = normalize_table_field(
                monitor,
                mkey="name",
                required_fields=['name'],
                field_name="monitor",
                example="[{'name': 'value'}]",
            )
        if internal_domain_list is not None:
            internal_domain_list = normalize_table_field(
                internal_domain_list,
                mkey="domain-name",
                required_fields=['domain-name'],
                field_name="internal_domain_list",
                example="[{'domain-name': 'value'}]",
            )
        if dns_suffix_search is not None:
            dns_suffix_search = normalize_table_field(
                dns_suffix_search,
                mkey="dns-suffix",
                required_fields=['dns-suffix'],
                field_name="dns_suffix_search",
                example="[{'dns-suffix': 'value'}]",
            )
        if ipv4_exclude_range is not None:
            ipv4_exclude_range = normalize_table_field(
                ipv4_exclude_range,
                mkey="id",
                required_fields=['id', 'start-ip', 'end-ip'],
                field_name="ipv4_exclude_range",
                example="[{'id': 1, 'start-ip': '192.168.1.10', 'end-ip': '192.168.1.10'}]",
            )
        if ipv6_exclude_range is not None:
            ipv6_exclude_range = normalize_table_field(
                ipv6_exclude_range,
                mkey="id",
                required_fields=['id', 'start-ip', 'end-ip'],
                field_name="ipv6_exclude_range",
                example="[{'id': 1, 'start-ip': 'value', 'end-ip': 'value'}]",
            )
        if backup_gateway is not None:
            backup_gateway = normalize_table_field(
                backup_gateway,
                mkey="address",
                required_fields=['address'],
                field_name="backup_gateway",
                example="[{'address': 'value'}]",
            )
        if remote_gw_ztna_tags is not None:
            remote_gw_ztna_tags = normalize_table_field(
                remote_gw_ztna_tags,
                mkey="name",
                required_fields=['name'],
                field_name="remote_gw_ztna_tags",
                example="[{'name': 'value'}]",
            )
        
        # Apply normalization for multi-value option fields (space-separated strings)
        
        # Build payload using helper function
        # Note: auto_normalize=False because this endpoint has unitary fields
        # (like 'interface') that would be incorrectly converted to list format
        payload_data = build_api_payload(
            auto_normalize=False,
            name=name,
            type=type,
            interface=interface,
            ip_version=ip_version,
            ike_version=ike_version,
            local_gw=local_gw,
            local_gw6=local_gw6,
            remote_gw=remote_gw,
            remote_gw6=remote_gw6,
            remotegw_ddns=remotegw_ddns,
            keylife=keylife,
            certificate=certificate,
            authmethod=authmethod,
            authmethod_remote=authmethod_remote,
            mode=mode,
            peertype=peertype,
            peerid=peerid,
            default_gw=default_gw,
            default_gw_priority=default_gw_priority,
            usrgrp=usrgrp,
            peer=peer,
            peergrp=peergrp,
            monitor=monitor,
            monitor_min=monitor_min,
            monitor_hold_down_type=monitor_hold_down_type,
            monitor_hold_down_delay=monitor_hold_down_delay,
            monitor_hold_down_weekday=monitor_hold_down_weekday,
            monitor_hold_down_time=monitor_hold_down_time,
            net_device=net_device,
            passive_mode=passive_mode,
            exchange_interface_ip=exchange_interface_ip,
            exchange_ip_addr4=exchange_ip_addr4,
            exchange_ip_addr6=exchange_ip_addr6,
            aggregate_member=aggregate_member,
            aggregate_weight=aggregate_weight,
            packet_redistribution=packet_redistribution,
            peer_egress_shaping=peer_egress_shaping,
            peer_egress_shaping_value=peer_egress_shaping_value,
            mode_cfg=mode_cfg,
            mode_cfg_allow_client_selector=mode_cfg_allow_client_selector,
            assign_ip=assign_ip,
            assign_ip_from=assign_ip_from,
            ipv4_start_ip=ipv4_start_ip,
            ipv4_end_ip=ipv4_end_ip,
            ipv4_netmask=ipv4_netmask,
            dhcp_ra_giaddr=dhcp_ra_giaddr,
            dhcp6_ra_linkaddr=dhcp6_ra_linkaddr,
            dns_mode=dns_mode,
            ipv4_dns_server1=ipv4_dns_server1,
            ipv4_dns_server2=ipv4_dns_server2,
            ipv4_dns_server3=ipv4_dns_server3,
            internal_domain_list=internal_domain_list,
            dns_suffix_search=dns_suffix_search,
            ipv4_wins_server1=ipv4_wins_server1,
            ipv4_wins_server2=ipv4_wins_server2,
            ipv4_exclude_range=ipv4_exclude_range,
            ipv4_split_include=ipv4_split_include,
            split_include_service=split_include_service,
            ipv4_name=ipv4_name,
            ipv6_start_ip=ipv6_start_ip,
            ipv6_end_ip=ipv6_end_ip,
            ipv6_prefix=ipv6_prefix,
            ipv6_dns_server1=ipv6_dns_server1,
            ipv6_dns_server2=ipv6_dns_server2,
            ipv6_dns_server3=ipv6_dns_server3,
            ipv6_exclude_range=ipv6_exclude_range,
            ipv6_split_include=ipv6_split_include,
            ipv6_name=ipv6_name,
            ip_delay_interval=ip_delay_interval,
            unity_support=unity_support,
            domain=domain,
            banner=banner,
            include_local_lan=include_local_lan,
            ipv4_split_exclude=ipv4_split_exclude,
            ipv6_split_exclude=ipv6_split_exclude,
            save_password=save_password,
            client_auto_negotiate=client_auto_negotiate,
            client_keep_alive=client_keep_alive,
            backup_gateway=backup_gateway,
            proposal=proposal,
            add_route=add_route,
            add_gw_route=add_gw_route,
            psksecret=psksecret,
            psksecret_remote=psksecret_remote,
            keepalive=keepalive,
            distance=distance,
            priority=priority,
            localid=localid,
            localid_type=localid_type,
            auto_negotiate=auto_negotiate,
            negotiate_timeout=negotiate_timeout,
            fragmentation=fragmentation,
            ip_fragmentation=ip_fragmentation,
            dpd=dpd,
            dpd_retrycount=dpd_retrycount,
            dpd_retryinterval=dpd_retryinterval,
            comments=comments,
            npu_offload=npu_offload,
            send_cert_chain=send_cert_chain,
            dhgrp=dhgrp,
            addke1=addke1,
            addke2=addke2,
            addke3=addke3,
            addke4=addke4,
            addke5=addke5,
            addke6=addke6,
            addke7=addke7,
            suite_b=suite_b,
            eap=eap,
            eap_identity=eap_identity,
            eap_exclude_peergrp=eap_exclude_peergrp,
            eap_cert_auth=eap_cert_auth,
            acct_verify=acct_verify,
            ppk=ppk,
            ppk_secret=ppk_secret,
            ppk_identity=ppk_identity,
            wizard_type=wizard_type,
            xauthtype=xauthtype,
            reauth=reauth,
            authusr=authusr,
            authpasswd=authpasswd,
            group_authentication=group_authentication,
            group_authentication_secret=group_authentication_secret,
            authusrgrp=authusrgrp,
            mesh_selector_type=mesh_selector_type,
            idle_timeout=idle_timeout,
            shared_idle_timeout=shared_idle_timeout,
            idle_timeoutinterval=idle_timeoutinterval,
            ha_sync_esp_seqno=ha_sync_esp_seqno,
            fgsp_sync=fgsp_sync,
            inbound_dscp_copy=inbound_dscp_copy,
            auto_discovery_sender=auto_discovery_sender,
            auto_discovery_receiver=auto_discovery_receiver,
            auto_discovery_forwarder=auto_discovery_forwarder,
            auto_discovery_psk=auto_discovery_psk,
            auto_discovery_shortcuts=auto_discovery_shortcuts,
            auto_discovery_crossover=auto_discovery_crossover,
            auto_discovery_offer_interval=auto_discovery_offer_interval,
            auto_discovery_dialup_placeholder=auto_discovery_dialup_placeholder,
            encapsulation=encapsulation,
            encapsulation_address=encapsulation_address,
            encap_local_gw4=encap_local_gw4,
            encap_local_gw6=encap_local_gw6,
            encap_remote_gw4=encap_remote_gw4,
            encap_remote_gw6=encap_remote_gw6,
            vni=vni,
            nattraversal=nattraversal,
            esn=esn,
            fragmentation_mtu=fragmentation_mtu,
            childless_ike=childless_ike,
            azure_ad_autoconnect=azure_ad_autoconnect,
            client_resume=client_resume,
            client_resume_interval=client_resume_interval,
            rekey=rekey,
            digital_signature_auth=digital_signature_auth,
            signature_hash_alg=signature_hash_alg,
            rsa_signature_format=rsa_signature_format,
            rsa_signature_hash_override=rsa_signature_hash_override,
            enforce_unique_id=enforce_unique_id,
            cert_id_validation=cert_id_validation,
            fec_egress=fec_egress,
            fec_send_timeout=fec_send_timeout,
            fec_base=fec_base,
            fec_codec=fec_codec,
            fec_redundant=fec_redundant,
            fec_ingress=fec_ingress,
            fec_receive_timeout=fec_receive_timeout,
            fec_health_check=fec_health_check,
            fec_mapping_profile=fec_mapping_profile,
            network_overlay=network_overlay,
            network_id=network_id,
            dev_id_notification=dev_id_notification,
            dev_id=dev_id,
            loopback_asymroute=loopback_asymroute,
            link_cost=link_cost,
            kms=kms,
            exchange_fgt_device_id=exchange_fgt_device_id,
            ipv6_auto_linklocal=ipv6_auto_linklocal,
            ems_sn_check=ems_sn_check,
            cert_trust_store=cert_trust_store,
            qkd=qkd,
            qkd_hybrid=qkd_hybrid,
            qkd_profile=qkd_profile,
            transport=transport,
            fortinet_esp=fortinet_esp,
            auto_transport_threshold=auto_transport_threshold,
            remote_gw_match=remote_gw_match,
            remote_gw_subnet=remote_gw_subnet,
            remote_gw_start_ip=remote_gw_start_ip,
            remote_gw_end_ip=remote_gw_end_ip,
            remote_gw_country=remote_gw_country,
            remote_gw_ztna_tags=remote_gw_ztna_tags,
            remote_gw6_match=remote_gw6_match,
            remote_gw6_subnet=remote_gw6_subnet,
            remote_gw6_start_ip=remote_gw6_start_ip,
            remote_gw6_end_ip=remote_gw6_end_ip,
            remote_gw6_country=remote_gw6_country,
            cert_peer_username_validation=cert_peer_username_validation,
            cert_peer_username_strip=cert_peer_username_strip,
            data=payload_dict,
        )
        
        # Check for deprecated fields and warn users
        from ._helpers.phase1_interface import DEPRECATED_FIELDS
        if DEPRECATED_FIELDS:
            from hfortix_core import check_deprecated_fields
            check_deprecated_fields(
                payload=payload_data,
                deprecated_fields=DEPRECATED_FIELDS,
                endpoint="cmdb/vpn/ipsec/phase1_interface",
            )
        
        name_value = payload_data.get("name")
        if not name_value:
            raise ValueError("name is required for PUT")
        endpoint = "/vpn.ipsec/phase1-interface/" + quote_path_param(name_value)

        # Add explicit query parameters for PUT
        params: dict[str, Any] = {}
        if q_action is not None:
            params["action"] = q_action
        if q_before is not None:
            params["before"] = q_before
        if q_after is not None:
            params["after"] = q_after
        if q_scope is not None:
            params["scope"] = q_scope
        
        return self._client.put(
            "cmdb", endpoint, data=payload_data, params=params, vdom=vdom        )

    # ========================================================================
    # POST Method
    # Type hints provided by CRUDEndpoint protocol (no local @overload needed)
    # ========================================================================
    
    def post(
        self,
        payload_dict: dict[str, Any] | None = None,
        name: str | None = None,
        type: Literal["static", "dynamic", "ddns"] | None = None,
        interface: str | None = None,
        ip_version: Literal["4", "6"] | None = None,
        ike_version: Literal["1", "2"] | None = None,
        local_gw: str | None = None,
        local_gw6: str | None = None,
        remote_gw: str | None = None,
        remote_gw6: str | None = None,
        remotegw_ddns: str | None = None,
        keylife: int | None = None,
        certificate: str | list[str] | list[dict[str, Any]] | None = None,
        authmethod: Literal["psk", "signature"] | None = None,
        authmethod_remote: Literal["psk", "signature"] | None = None,
        mode: Literal["aggressive", "main"] | None = None,
        peertype: Literal["any", "one", "dialup", "peer", "peergrp"] | None = None,
        peerid: str | None = None,
        default_gw: str | None = None,
        default_gw_priority: int | None = None,
        usrgrp: str | None = None,
        peer: str | None = None,
        peergrp: str | None = None,
        monitor: str | list[str] | list[dict[str, Any]] | None = None,
        monitor_min: int | None = None,
        monitor_hold_down_type: Literal["immediate", "delay", "time"] | None = None,
        monitor_hold_down_delay: int | None = None,
        monitor_hold_down_weekday: Literal["everyday", "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"] | None = None,
        monitor_hold_down_time: str | None = None,
        net_device: Literal["enable", "disable"] | None = None,
        passive_mode: Literal["enable", "disable"] | None = None,
        exchange_interface_ip: Literal["enable", "disable"] | None = None,
        exchange_ip_addr4: str | None = None,
        exchange_ip_addr6: str | None = None,
        aggregate_member: Literal["enable", "disable"] | None = None,
        aggregate_weight: int | None = None,
        packet_redistribution: Literal["enable", "disable"] | None = None,
        peer_egress_shaping: Literal["enable", "disable"] | None = None,
        peer_egress_shaping_value: int | None = None,
        mode_cfg: Literal["disable", "enable"] | None = None,
        mode_cfg_allow_client_selector: Literal["disable", "enable"] | None = None,
        assign_ip: Literal["disable", "enable"] | None = None,
        assign_ip_from: Literal["range", "usrgrp", "dhcp", "name"] | None = None,
        ipv4_start_ip: str | None = None,
        ipv4_end_ip: str | None = None,
        ipv4_netmask: str | None = None,
        dhcp_ra_giaddr: str | None = None,
        dhcp6_ra_linkaddr: str | None = None,
        dns_mode: Literal["manual", "auto"] | None = None,
        ipv4_dns_server1: str | None = None,
        ipv4_dns_server2: str | None = None,
        ipv4_dns_server3: str | None = None,
        internal_domain_list: str | list[str] | list[dict[str, Any]] | None = None,
        dns_suffix_search: str | list[str] | list[dict[str, Any]] | None = None,
        ipv4_wins_server1: str | None = None,
        ipv4_wins_server2: str | None = None,
        ipv4_exclude_range: str | list[str] | list[dict[str, Any]] | None = None,
        ipv4_split_include: str | None = None,
        split_include_service: str | None = None,
        ipv4_name: str | None = None,
        ipv6_start_ip: str | None = None,
        ipv6_end_ip: str | None = None,
        ipv6_prefix: int | None = None,
        ipv6_dns_server1: str | None = None,
        ipv6_dns_server2: str | None = None,
        ipv6_dns_server3: str | None = None,
        ipv6_exclude_range: str | list[str] | list[dict[str, Any]] | None = None,
        ipv6_split_include: str | None = None,
        ipv6_name: str | None = None,
        ip_delay_interval: int | None = None,
        unity_support: Literal["disable", "enable"] | None = None,
        domain: str | None = None,
        banner: str | None = None,
        include_local_lan: Literal["disable", "enable"] | None = None,
        ipv4_split_exclude: str | None = None,
        ipv6_split_exclude: str | None = None,
        save_password: Literal["disable", "enable"] | None = None,
        client_auto_negotiate: Literal["disable", "enable"] | None = None,
        client_keep_alive: Literal["disable", "enable"] | None = None,
        backup_gateway: str | list[str] | list[dict[str, Any]] | None = None,
        proposal: Literal["des-md5", "des-sha1", "des-sha256", "des-sha384", "des-sha512", "3des-md5", "3des-sha1", "3des-sha256", "3des-sha384", "3des-sha512", "aes128-md5", "aes128-sha1", "aes128-sha256", "aes128-sha384", "aes128-sha512", "aes128gcm-prfsha1", "aes128gcm-prfsha256", "aes128gcm-prfsha384", "aes128gcm-prfsha512", "aes192-md5", "aes192-sha1", "aes192-sha256", "aes192-sha384", "aes192-sha512", "aes256-md5", "aes256-sha1", "aes256-sha256", "aes256-sha384", "aes256-sha512", "aes256gcm-prfsha1", "aes256gcm-prfsha256", "aes256gcm-prfsha384", "aes256gcm-prfsha512", "chacha20poly1305-prfsha1", "chacha20poly1305-prfsha256", "chacha20poly1305-prfsha384", "chacha20poly1305-prfsha512", "aria128-md5", "aria128-sha1", "aria128-sha256", "aria128-sha384", "aria128-sha512", "aria192-md5", "aria192-sha1", "aria192-sha256", "aria192-sha384", "aria192-sha512", "aria256-md5", "aria256-sha1", "aria256-sha256", "aria256-sha384", "aria256-sha512", "seed-md5", "seed-sha1", "seed-sha256", "seed-sha384", "seed-sha512"] | list[str] | None = None,
        add_route: Literal["disable", "enable"] | None = None,
        add_gw_route: Literal["enable", "disable"] | None = None,
        psksecret: Any | None = None,
        psksecret_remote: Any | None = None,
        keepalive: int | None = None,
        distance: int | None = None,
        priority: int | None = None,
        localid: str | None = None,
        localid_type: Literal["auto", "fqdn", "user-fqdn", "keyid", "address", "asn1dn"] | None = None,
        auto_negotiate: Literal["enable", "disable"] | None = None,
        negotiate_timeout: int | None = None,
        fragmentation: Literal["enable", "disable"] | None = None,
        ip_fragmentation: Literal["pre-encapsulation", "post-encapsulation"] | None = None,
        dpd: Literal["disable", "on-idle", "on-demand"] | None = None,
        dpd_retrycount: int | None = None,
        dpd_retryinterval: str | None = None,
        comments: str | None = None,
        npu_offload: Literal["enable", "disable"] | None = None,
        send_cert_chain: Literal["enable", "disable"] | None = None,
        dhgrp: Literal["1", "2", "5", "14", "15", "16", "17", "18", "19", "20", "21", "27", "28", "29", "30", "31", "32"] | list[str] | None = None,
        addke1: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke2: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke3: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke4: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke5: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke6: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        addke7: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | None = None,
        suite_b: Literal["disable", "suite-b-gcm-128", "suite-b-gcm-256"] | None = None,
        eap: Literal["enable", "disable"] | None = None,
        eap_identity: Literal["use-id-payload", "send-request"] | None = None,
        eap_exclude_peergrp: str | None = None,
        eap_cert_auth: Literal["enable", "disable"] | None = None,
        acct_verify: Literal["enable", "disable"] | None = None,
        ppk: Literal["disable", "allow", "require"] | None = None,
        ppk_secret: Any | None = None,
        ppk_identity: str | None = None,
        wizard_type: Literal["custom", "dialup-forticlient", "dialup-ios", "dialup-android", "dialup-windows", "dialup-cisco", "static-fortigate", "dialup-fortigate", "static-cisco", "dialup-cisco-fw", "simplified-static-fortigate", "hub-fortigate-auto-discovery", "spoke-fortigate-auto-discovery", "fabric-overlay-orchestrator"] | None = None,
        xauthtype: Literal["disable", "client", "pap", "chap", "auto"] | None = None,
        reauth: Literal["disable", "enable"] | None = None,
        authusr: str | None = None,
        authpasswd: Any | None = None,
        group_authentication: Literal["enable", "disable"] | None = None,
        group_authentication_secret: Any | None = None,
        authusrgrp: str | None = None,
        mesh_selector_type: Literal["disable", "subnet", "host"] | None = None,
        idle_timeout: Literal["enable", "disable"] | None = None,
        shared_idle_timeout: Literal["enable", "disable"] | None = None,
        idle_timeoutinterval: int | None = None,
        ha_sync_esp_seqno: Literal["enable", "disable"] | None = None,
        fgsp_sync: Literal["enable", "disable"] | None = None,
        inbound_dscp_copy: Literal["enable", "disable"] | None = None,
        auto_discovery_sender: Literal["enable", "disable"] | None = None,
        auto_discovery_receiver: Literal["enable", "disable"] | None = None,
        auto_discovery_forwarder: Literal["enable", "disable"] | None = None,
        auto_discovery_psk: Literal["enable", "disable"] | None = None,
        auto_discovery_shortcuts: Literal["independent", "dependent"] | None = None,
        auto_discovery_crossover: Literal["allow", "block"] | None = None,
        auto_discovery_offer_interval: int | None = None,
        auto_discovery_dialup_placeholder: Literal["disable", "enable"] | None = None,
        encapsulation: Literal["none", "gre", "vxlan", "vpn-id-ipip"] | None = None,
        encapsulation_address: Literal["ike", "ipv4", "ipv6"] | None = None,
        encap_local_gw4: str | None = None,
        encap_local_gw6: str | None = None,
        encap_remote_gw4: str | None = None,
        encap_remote_gw6: str | None = None,
        vni: int | None = None,
        nattraversal: Literal["enable", "disable", "forced"] | None = None,
        esn: Literal["require", "allow", "disable"] | None = None,
        fragmentation_mtu: int | None = None,
        childless_ike: Literal["enable", "disable"] | None = None,
        azure_ad_autoconnect: Literal["enable", "disable"] | None = None,
        client_resume: Literal["enable", "disable"] | None = None,
        client_resume_interval: int | None = None,
        rekey: Literal["enable", "disable"] | None = None,
        digital_signature_auth: Literal["enable", "disable"] | None = None,
        signature_hash_alg: Literal["sha1", "sha2-256", "sha2-384", "sha2-512"] | list[str] | None = None,
        rsa_signature_format: Literal["pkcs1", "pss"] | None = None,
        rsa_signature_hash_override: Literal["enable", "disable"] | None = None,
        enforce_unique_id: Literal["disable", "keep-new", "keep-old"] | None = None,
        cert_id_validation: Literal["enable", "disable"] | None = None,
        fec_egress: Literal["enable", "disable"] | None = None,
        fec_send_timeout: int | None = None,
        fec_base: int | None = None,
        fec_codec: Literal["rs", "xor"] | None = None,
        fec_redundant: int | None = None,
        fec_ingress: Literal["enable", "disable"] | None = None,
        fec_receive_timeout: int | None = None,
        fec_health_check: str | None = None,
        fec_mapping_profile: str | None = None,
        network_overlay: Literal["disable", "enable"] | None = None,
        network_id: int | None = None,
        dev_id_notification: Literal["disable", "enable"] | None = None,
        dev_id: str | None = None,
        loopback_asymroute: Literal["enable", "disable"] | None = None,
        link_cost: int | None = None,
        kms: str | None = None,
        exchange_fgt_device_id: Literal["enable", "disable"] | None = None,
        ipv6_auto_linklocal: Literal["enable", "disable"] | None = None,
        ems_sn_check: Literal["enable", "disable"] | None = None,
        cert_trust_store: Literal["local", "ems"] | None = None,
        qkd: Literal["disable", "allow", "require"] | None = None,
        qkd_hybrid: Literal["disable", "allow", "require"] | None = None,
        qkd_profile: str | None = None,
        transport: Literal["udp", "auto", "tcp"] | None = None,
        fortinet_esp: Literal["enable", "disable"] | None = None,
        auto_transport_threshold: int | None = None,
        remote_gw_match: Literal["any", "ipmask", "iprange", "geography", "ztna"] | None = None,
        remote_gw_subnet: Any | None = None,
        remote_gw_start_ip: str | None = None,
        remote_gw_end_ip: str | None = None,
        remote_gw_country: str | None = None,
        remote_gw_ztna_tags: str | list[str] | list[dict[str, Any]] | None = None,
        remote_gw6_match: Literal["any", "ipprefix", "iprange", "geography"] | None = None,
        remote_gw6_subnet: str | None = None,
        remote_gw6_start_ip: str | None = None,
        remote_gw6_end_ip: str | None = None,
        remote_gw6_country: str | None = None,
        cert_peer_username_validation: Literal["none", "othername", "rfc822name", "cn"] | None = None,
        cert_peer_username_strip: Literal["disable", "enable"] | None = None,
        q_action: Literal["clone"] | None = None,
        q_nkey: str | None = None,
        q_scope: str | None = None,
        vdom: str | bool | None = None,
        error_mode: Literal["raise", "return", "print"] | None = None,
        error_format: Literal["detailed", "simple", "code_only"] | None = None,
    ):  # type: ignore[no-untyped-def]
        """
        Create new vpn/ipsec/phase1_interface object.

        Configure VPN remote gateway.

        Args:
            payload_dict: Complete object data as dict. Alternative to individual parameters.
            name: IPsec remote gateway name.
            type: Remote gateway type.
            interface: Local physical, aggregate, or VLAN outgoing interface.
            ip_version: IP version to use for VPN interface.
            ike_version: IKE protocol version.
            local_gw: IPv4 address of the local gateway's external interface.
            local_gw6: IPv6 address of the local gateway's external interface.
            remote_gw: IPv4 address of the remote gateway's external interface.
            remote_gw6: IPv6 address of the remote gateway's external interface.
            remotegw_ddns: Domain name of remote gateway. For example, name.ddns.com.
            keylife: Time to wait in seconds before phase 1 encryption key expires.
            certificate: The names of up to 4 signed personal certificates.
                Default format: [{'name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'name': 'val1'}, ...]
                  - List of dicts: [{'name': 'value'}] (recommended)
            authmethod: Authentication method.
            authmethod_remote: Authentication method (remote side).
            mode: The ID protection mode used to establish a secure channel.
            peertype: Accept this peer type.
            peerid: Accept this peer identity.
            default_gw: IPv4 address of default route gateway to use for traffic exiting the interface.
            default_gw_priority: Priority for default gateway route. A higher priority number signifies a less preferred route.
            usrgrp: User group name for dialup peers.
            peer: Accept this peer certificate.
            peergrp: Accept this peer certificate group.
            monitor: IPsec interface as backup for primary interface.
                Default format: [{'name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'name': 'val1'}, ...]
                  - List of dicts: [{'name': 'value'}] (recommended)
            monitor_min: Minimum number of links to become degraded before activating this interface.  Zero (0) means all links must be down before activating this interface.
            monitor_hold_down_type: Recovery time method when primary interface re-establishes.
            monitor_hold_down_delay: Time to wait in seconds before recovery once primary re-establishes.
            monitor_hold_down_weekday: Day of the week to recover once primary re-establishes.
            monitor_hold_down_time: Time of day at which to fail back to primary after it re-establishes.
            net_device: Enable/disable kernel device creation.
            passive_mode: Enable/disable IPsec passive mode for static tunnels.
            exchange_interface_ip: Enable/disable exchange of IPsec interface IP address.
            exchange_ip_addr4: IPv4 address to exchange with peers.
            exchange_ip_addr6: IPv6 address to exchange with peers.
            aggregate_member: Enable/disable use as an aggregate member.
            aggregate_weight: Link weight for aggregate.
            packet_redistribution: Enable/disable packet distribution (RPS) on the IPsec interface.
            peer_egress_shaping: Enable/disable peer egress shaping.
            peer_egress_shaping_value: Configure outbound bandwidth to use for peer egress shaping in kbps (0 - 80000000, default = 0).
            mode_cfg: Enable/disable configuration method.
            mode_cfg_allow_client_selector: Enable/disable mode-cfg client to use custom phase2 selectors.
            assign_ip: Enable/disable assignment of IP to IPsec interface via configuration method.
            assign_ip_from: Method by which the IP address will be assigned.
            ipv4_start_ip: Start of IPv4 range.
            ipv4_end_ip: End of IPv4 range.
            ipv4_netmask: IPv4 Netmask.
            dhcp_ra_giaddr: Relay agent gateway IP address to use in the giaddr field of DHCP requests.
            dhcp6_ra_linkaddr: Relay agent IPv6 link address to use in DHCP6 requests.
            dns_mode: DNS server mode.
            ipv4_dns_server1: IPv4 DNS server 1.
            ipv4_dns_server2: IPv4 DNS server 2.
            ipv4_dns_server3: IPv4 DNS server 3.
            internal_domain_list: One or more internal domain names in quotes separated by spaces.
                Default format: [{'domain-name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'domain-name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'domain-name': 'val1'}, ...]
                  - List of dicts: [{'domain-name': 'value'}] (recommended)
            dns_suffix_search: One or more DNS domain name suffixes in quotes separated by spaces.
                Default format: [{'dns-suffix': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'dns-suffix': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'dns-suffix': 'val1'}, ...]
                  - List of dicts: [{'dns-suffix': 'value'}] (recommended)
            ipv4_wins_server1: WINS server 1.
            ipv4_wins_server2: WINS server 2.
            ipv4_exclude_range: Configuration Method IPv4 exclude ranges.
                Default format: [{'id': 1, 'start-ip': '192.168.1.10', 'end-ip': '192.168.1.10'}]
                Required format: List of dicts with keys: id, start-ip, end-ip
                  (String format not allowed due to multiple required fields)
            ipv4_split_include: IPv4 split-include subnets.
            split_include_service: Split-include services.
            ipv4_name: IPv4 address name.
            ipv6_start_ip: Start of IPv6 range.
            ipv6_end_ip: End of IPv6 range.
            ipv6_prefix: IPv6 prefix.
            ipv6_dns_server1: IPv6 DNS server 1.
            ipv6_dns_server2: IPv6 DNS server 2.
            ipv6_dns_server3: IPv6 DNS server 3.
            ipv6_exclude_range: Configuration method IPv6 exclude ranges.
                Default format: [{'id': 1, 'start-ip': 'value', 'end-ip': 'value'}]
                Required format: List of dicts with keys: id, start-ip, end-ip
                  (String format not allowed due to multiple required fields)
            ipv6_split_include: IPv6 split-include subnets.
            ipv6_name: IPv6 address name.
            ip_delay_interval: IP address reuse delay interval in seconds (0 - 28800).
            unity_support: Enable/disable support for Cisco UNITY Configuration Method extensions.
            domain: Instruct unity clients about the single default DNS domain.
            banner: Message that unity client should display after connecting.
            include_local_lan: Enable/disable allow local LAN access on unity clients.
            ipv4_split_exclude: IPv4 subnets that should not be sent over the IPsec tunnel.
            ipv6_split_exclude: IPv6 subnets that should not be sent over the IPsec tunnel.
            save_password: Enable/disable saving XAuth username and password on VPN clients.
            client_auto_negotiate: Enable/disable allowing the VPN client to bring up the tunnel when there is no traffic.
            client_keep_alive: Enable/disable allowing the VPN client to keep the tunnel up when there is no traffic.
            backup_gateway: Instruct unity clients about the backup gateway address(es).
                Default format: [{'address': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'address': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'address': 'val1'}, ...]
                  - List of dicts: [{'address': 'value'}] (recommended)
            proposal: Phase1 proposal.
            add_route: Enable/disable control addition of a route to peer destination selector.
            add_gw_route: Enable/disable automatically add a route to the remote gateway.
            psksecret: Pre-shared secret for PSK authentication (ASCII string or hexadecimal encoded with a leading 0x).
            psksecret_remote: Pre-shared secret for remote side PSK authentication (ASCII string or hexadecimal encoded with a leading 0x).
            keepalive: NAT-T keep alive interval.
            distance: Distance for routes added by IKE (1 - 255).
            priority: Priority for routes added by IKE (1 - 65535).
            localid: Local ID.
            localid_type: Local ID type.
            auto_negotiate: Enable/disable automatic initiation of IKE SA negotiation.
            negotiate_timeout: IKE SA negotiation timeout in seconds (1 - 300).
            fragmentation: Enable/disable fragment IKE message on re-transmission.
            ip_fragmentation: Determine whether IP packets are fragmented before or after IPsec encapsulation.
            dpd: Dead Peer Detection mode.
            dpd_retrycount: Number of DPD retry attempts.
            dpd_retryinterval: DPD retry interval.
            comments: Comment.
            npu_offload: Enable/disable offloading NPU.
            send_cert_chain: Enable/disable sending certificate chain.
            dhgrp: DH group.
            addke1: ADDKE1 group.
            addke2: ADDKE2 group.
            addke3: ADDKE3 group.
            addke4: ADDKE4 group.
            addke5: ADDKE5 group.
            addke6: ADDKE6 group.
            addke7: ADDKE7 group.
            suite_b: Use Suite-B.
            eap: Enable/disable IKEv2 EAP authentication.
            eap_identity: IKEv2 EAP peer identity type.
            eap_exclude_peergrp: Peer group excluded from EAP authentication.
            eap_cert_auth: Enable/disable peer certificate authentication in addition to EAP if peer is a FortiClient endpoint.
            acct_verify: Enable/disable verification of RADIUS accounting record.
            ppk: Enable/disable IKEv2 Postquantum Preshared Key (PPK).
            ppk_secret: IKEv2 Postquantum Preshared Key (ASCII string or hexadecimal encoded with a leading 0x).
            ppk_identity: IKEv2 Postquantum Preshared Key Identity.
            wizard_type: GUI VPN Wizard Type.
            xauthtype: XAuth type.
            reauth: Enable/disable re-authentication upon IKE SA lifetime expiration.
            authusr: XAuth user name.
            authpasswd: XAuth password (max 35 characters).
            group_authentication: Enable/disable IKEv2 IDi group authentication.
            group_authentication_secret: Password for IKEv2 ID group authentication. ASCII string or hexadecimal indicated by a leading 0x.
            authusrgrp: Authentication user group.
            mesh_selector_type: Add selectors containing subsets of the configuration depending on traffic.
            idle_timeout: Enable/disable IPsec tunnel idle timeout.
            shared_idle_timeout: Enable/disable IPsec tunnel shared idle timeout.
            idle_timeoutinterval: IPsec tunnel idle timeout in minutes (5 - 43200).
            ha_sync_esp_seqno: Enable/disable sequence number jump ahead for IPsec HA.
            fgsp_sync: Enable/disable IPsec syncing of tunnels for FGSP IPsec.
            inbound_dscp_copy: Enable/disable copy the dscp in the ESP header to the inner IP Header.
            auto_discovery_sender: Enable/disable sending auto-discovery short-cut messages.
            auto_discovery_receiver: Enable/disable accepting auto-discovery short-cut messages.
            auto_discovery_forwarder: Enable/disable forwarding auto-discovery short-cut messages.
            auto_discovery_psk: Enable/disable use of pre-shared secrets for authentication of auto-discovery tunnels.
            auto_discovery_shortcuts: Control deletion of child short-cut tunnels when the parent tunnel goes down.
            auto_discovery_crossover: Allow/block set-up of short-cut tunnels between different network IDs.
            auto_discovery_offer_interval: Interval between shortcut offer messages in seconds (1 - 300, default = 5).
            auto_discovery_dialup_placeholder: Control if this dynamic gateway is used for shortcut connections only.
            encapsulation: Enable/disable GRE/VXLAN/VPNID encapsulation.
            encapsulation_address: Source for GRE/VXLAN tunnel address.
            encap_local_gw4: Local IPv4 address of GRE/VXLAN tunnel.
            encap_local_gw6: Local IPv6 address of GRE/VXLAN tunnel.
            encap_remote_gw4: Remote IPv4 address of GRE/VXLAN tunnel.
            encap_remote_gw6: Remote IPv6 address of GRE/VXLAN tunnel.
            vni: VNI of VXLAN tunnel.
            nattraversal: Enable/disable NAT traversal.
            esn: Extended sequence number (ESN) negotiation.
            fragmentation_mtu: IKE fragmentation MTU (500 - 16000).
            childless_ike: Enable/disable childless IKEv2 initiation (RFC 6023).
            azure_ad_autoconnect: Enable/disable Azure AD Auto-Connect for FortiClient.
            client_resume: Enable/disable resumption of offline FortiClient sessions.  When a FortiClient enabled laptop is closed or enters sleep/hibernate mode, enabling this feature allows FortiClient to keep the tunnel during this period, and allows users to immediately resume using the IPsec tunnel when the device wakes up.
            client_resume_interval: Maximum time in seconds during which a VPN client may resume using a tunnel after a client PC has entered sleep mode or temporarily lost its network connection (120 - 172800, default = 7200).
            rekey: Enable/disable phase1 rekey.
            digital_signature_auth: Enable/disable IKEv2 Digital Signature Authentication (RFC 7427).
            signature_hash_alg: Digital Signature Authentication hash algorithms.
            rsa_signature_format: Digital Signature Authentication RSA signature format.
            rsa_signature_hash_override: Enable/disable IKEv2 RSA signature hash algorithm override.
            enforce_unique_id: Enable/disable peer ID uniqueness check.
            cert_id_validation: Enable/disable cross validation of peer ID and the identity in the peer's certificate as specified in RFC 4945.
            fec_egress: Enable/disable Forward Error Correction for egress IPsec traffic.
            fec_send_timeout: Timeout in milliseconds before sending Forward Error Correction packets (1 - 1000).
            fec_base: Number of base Forward Error Correction packets (1 - 20).
            fec_codec: Forward Error Correction encoding/decoding algorithm.
            fec_redundant: Number of redundant Forward Error Correction packets (1 - 5 for reed-solomon, 1 for xor).
            fec_ingress: Enable/disable Forward Error Correction for ingress IPsec traffic.
            fec_receive_timeout: Timeout in milliseconds before dropping Forward Error Correction packets (1 - 1000).
            fec_health_check: SD-WAN health check.
            fec_mapping_profile: Forward Error Correction (FEC) mapping profile.
            network_overlay: Enable/disable network overlays.
            network_id: VPN gateway network ID.
            dev_id_notification: Enable/disable device ID notification.
            dev_id: Device ID carried by the device ID notification.
            loopback_asymroute: Enable/disable asymmetric routing for IKE traffic on loopback interface.
            link_cost: VPN tunnel underlay link cost.
            kms: Key Management Services server.
            exchange_fgt_device_id: Enable/disable device identifier exchange with peer FortiGate units for use of VPN monitor data by FortiManager.
            ipv6_auto_linklocal: Enable/disable auto generation of IPv6 link-local address using last 8 bytes of mode-cfg assigned IPv6 address.
            ems_sn_check: Enable/disable verification of EMS serial number.
            cert_trust_store: CA certificate trust store.
            qkd: Enable/disable use of Quantum Key Distribution (QKD) server.
            qkd_hybrid: Enable/disable use of Quantum Key Distribution (QKD) hybrid keys.
            qkd_profile: Quantum Key Distribution (QKD) server profile.
            transport: Set IKE transport protocol.
            fortinet_esp: Enable/disable Fortinet ESP encapsulation.
            auto_transport_threshold: Timeout in seconds before falling back to next transport protocol.
            remote_gw_match: Set type of IPv4 remote gateway address matching.
            remote_gw_subnet: IPv4 address and subnet mask.
            remote_gw_start_ip: First IPv4 address in the range.
            remote_gw_end_ip: Last IPv4 address in the range.
            remote_gw_country: IPv4 addresses associated to a specific country.
            remote_gw_ztna_tags: IPv4 ZTNA posture tags.
                Default format: [{'name': 'value'}]
                Supported formats:
                  - Single string: "value" → [{'name': 'value'}]
                  - List of strings: ["val1", "val2"] → [{'name': 'val1'}, ...]
                  - List of dicts: [{'name': 'value'}] (recommended)
            remote_gw6_match: Set type of IPv6 remote gateway address matching.
            remote_gw6_subnet: IPv6 address and prefix.
            remote_gw6_start_ip: First IPv6 address in the range.
            remote_gw6_end_ip: Last IPv6 address in the range.
            remote_gw6_country: IPv6 addresses associated to a specific country.
            cert_peer_username_validation: Enable/disable cross validation of peer username and the identity in the peer's certificate.
            cert_peer_username_strip: Enable/disable domain stripping on certificate identity.
            vdom: Virtual domain name. Use True for global, string for specific VDOM.
            error_mode: Override client-level error_mode. "raise" raises exceptions, "return" returns error dict, "print" prints errors.
            error_format: Override client-level error_format. "detailed" provides full context, "simple" is concise, "code_only" returns just status code.

        Returns:
            FortiObject instance with created object. Use .dict, .json, or .raw to access as dictionary.

        Examples:
            >>> # Create using individual parameters
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.post(
            ...     name="example",
            ...     # ... other required fields
            ... )
            >>> print(f"Created name: {result['results']}")
            
            >>> # Create using payload dict
            >>> payload = Phase1Interface.defaults()  # Start with defaults
            >>> payload['name'] = 'my-object'
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.post(payload_dict=payload)

        Note:
            Required fields: {{ ", ".join(Phase1Interface.required_fields()) }}
            
            Use Phase1Interface.help('field_name') to get field details.

        See Also:
            - get(): Retrieve objects
            - put(): Update existing object
            - set(): Intelligent create or update
        """
        # Apply normalization for table fields (supports flexible input formats)
        if certificate is not None:
            certificate = normalize_table_field(
                certificate,
                mkey="name",
                required_fields=['name'],
                field_name="certificate",
                example="[{'name': 'value'}]",
            )
        if monitor is not None:
            monitor = normalize_table_field(
                monitor,
                mkey="name",
                required_fields=['name'],
                field_name="monitor",
                example="[{'name': 'value'}]",
            )
        if internal_domain_list is not None:
            internal_domain_list = normalize_table_field(
                internal_domain_list,
                mkey="domain-name",
                required_fields=['domain-name'],
                field_name="internal_domain_list",
                example="[{'domain-name': 'value'}]",
            )
        if dns_suffix_search is not None:
            dns_suffix_search = normalize_table_field(
                dns_suffix_search,
                mkey="dns-suffix",
                required_fields=['dns-suffix'],
                field_name="dns_suffix_search",
                example="[{'dns-suffix': 'value'}]",
            )
        if ipv4_exclude_range is not None:
            ipv4_exclude_range = normalize_table_field(
                ipv4_exclude_range,
                mkey="id",
                required_fields=['id', 'start-ip', 'end-ip'],
                field_name="ipv4_exclude_range",
                example="[{'id': 1, 'start-ip': '192.168.1.10', 'end-ip': '192.168.1.10'}]",
            )
        if ipv6_exclude_range is not None:
            ipv6_exclude_range = normalize_table_field(
                ipv6_exclude_range,
                mkey="id",
                required_fields=['id', 'start-ip', 'end-ip'],
                field_name="ipv6_exclude_range",
                example="[{'id': 1, 'start-ip': 'value', 'end-ip': 'value'}]",
            )
        if backup_gateway is not None:
            backup_gateway = normalize_table_field(
                backup_gateway,
                mkey="address",
                required_fields=['address'],
                field_name="backup_gateway",
                example="[{'address': 'value'}]",
            )
        if remote_gw_ztna_tags is not None:
            remote_gw_ztna_tags = normalize_table_field(
                remote_gw_ztna_tags,
                mkey="name",
                required_fields=['name'],
                field_name="remote_gw_ztna_tags",
                example="[{'name': 'value'}]",
            )
        
        # Apply normalization for multi-value option fields (space-separated strings)
        
        # Build payload using helper function
        # Note: auto_normalize=False because this endpoint has unitary fields
        # (like 'interface') that would be incorrectly converted to list format
        payload_data = build_api_payload(
            auto_normalize=False,
            name=name,
            type=type,
            interface=interface,
            ip_version=ip_version,
            ike_version=ike_version,
            local_gw=local_gw,
            local_gw6=local_gw6,
            remote_gw=remote_gw,
            remote_gw6=remote_gw6,
            remotegw_ddns=remotegw_ddns,
            keylife=keylife,
            certificate=certificate,
            authmethod=authmethod,
            authmethod_remote=authmethod_remote,
            mode=mode,
            peertype=peertype,
            peerid=peerid,
            default_gw=default_gw,
            default_gw_priority=default_gw_priority,
            usrgrp=usrgrp,
            peer=peer,
            peergrp=peergrp,
            monitor=monitor,
            monitor_min=monitor_min,
            monitor_hold_down_type=monitor_hold_down_type,
            monitor_hold_down_delay=monitor_hold_down_delay,
            monitor_hold_down_weekday=monitor_hold_down_weekday,
            monitor_hold_down_time=monitor_hold_down_time,
            net_device=net_device,
            passive_mode=passive_mode,
            exchange_interface_ip=exchange_interface_ip,
            exchange_ip_addr4=exchange_ip_addr4,
            exchange_ip_addr6=exchange_ip_addr6,
            aggregate_member=aggregate_member,
            aggregate_weight=aggregate_weight,
            packet_redistribution=packet_redistribution,
            peer_egress_shaping=peer_egress_shaping,
            peer_egress_shaping_value=peer_egress_shaping_value,
            mode_cfg=mode_cfg,
            mode_cfg_allow_client_selector=mode_cfg_allow_client_selector,
            assign_ip=assign_ip,
            assign_ip_from=assign_ip_from,
            ipv4_start_ip=ipv4_start_ip,
            ipv4_end_ip=ipv4_end_ip,
            ipv4_netmask=ipv4_netmask,
            dhcp_ra_giaddr=dhcp_ra_giaddr,
            dhcp6_ra_linkaddr=dhcp6_ra_linkaddr,
            dns_mode=dns_mode,
            ipv4_dns_server1=ipv4_dns_server1,
            ipv4_dns_server2=ipv4_dns_server2,
            ipv4_dns_server3=ipv4_dns_server3,
            internal_domain_list=internal_domain_list,
            dns_suffix_search=dns_suffix_search,
            ipv4_wins_server1=ipv4_wins_server1,
            ipv4_wins_server2=ipv4_wins_server2,
            ipv4_exclude_range=ipv4_exclude_range,
            ipv4_split_include=ipv4_split_include,
            split_include_service=split_include_service,
            ipv4_name=ipv4_name,
            ipv6_start_ip=ipv6_start_ip,
            ipv6_end_ip=ipv6_end_ip,
            ipv6_prefix=ipv6_prefix,
            ipv6_dns_server1=ipv6_dns_server1,
            ipv6_dns_server2=ipv6_dns_server2,
            ipv6_dns_server3=ipv6_dns_server3,
            ipv6_exclude_range=ipv6_exclude_range,
            ipv6_split_include=ipv6_split_include,
            ipv6_name=ipv6_name,
            ip_delay_interval=ip_delay_interval,
            unity_support=unity_support,
            domain=domain,
            banner=banner,
            include_local_lan=include_local_lan,
            ipv4_split_exclude=ipv4_split_exclude,
            ipv6_split_exclude=ipv6_split_exclude,
            save_password=save_password,
            client_auto_negotiate=client_auto_negotiate,
            client_keep_alive=client_keep_alive,
            backup_gateway=backup_gateway,
            proposal=proposal,
            add_route=add_route,
            add_gw_route=add_gw_route,
            psksecret=psksecret,
            psksecret_remote=psksecret_remote,
            keepalive=keepalive,
            distance=distance,
            priority=priority,
            localid=localid,
            localid_type=localid_type,
            auto_negotiate=auto_negotiate,
            negotiate_timeout=negotiate_timeout,
            fragmentation=fragmentation,
            ip_fragmentation=ip_fragmentation,
            dpd=dpd,
            dpd_retrycount=dpd_retrycount,
            dpd_retryinterval=dpd_retryinterval,
            comments=comments,
            npu_offload=npu_offload,
            send_cert_chain=send_cert_chain,
            dhgrp=dhgrp,
            addke1=addke1,
            addke2=addke2,
            addke3=addke3,
            addke4=addke4,
            addke5=addke5,
            addke6=addke6,
            addke7=addke7,
            suite_b=suite_b,
            eap=eap,
            eap_identity=eap_identity,
            eap_exclude_peergrp=eap_exclude_peergrp,
            eap_cert_auth=eap_cert_auth,
            acct_verify=acct_verify,
            ppk=ppk,
            ppk_secret=ppk_secret,
            ppk_identity=ppk_identity,
            wizard_type=wizard_type,
            xauthtype=xauthtype,
            reauth=reauth,
            authusr=authusr,
            authpasswd=authpasswd,
            group_authentication=group_authentication,
            group_authentication_secret=group_authentication_secret,
            authusrgrp=authusrgrp,
            mesh_selector_type=mesh_selector_type,
            idle_timeout=idle_timeout,
            shared_idle_timeout=shared_idle_timeout,
            idle_timeoutinterval=idle_timeoutinterval,
            ha_sync_esp_seqno=ha_sync_esp_seqno,
            fgsp_sync=fgsp_sync,
            inbound_dscp_copy=inbound_dscp_copy,
            auto_discovery_sender=auto_discovery_sender,
            auto_discovery_receiver=auto_discovery_receiver,
            auto_discovery_forwarder=auto_discovery_forwarder,
            auto_discovery_psk=auto_discovery_psk,
            auto_discovery_shortcuts=auto_discovery_shortcuts,
            auto_discovery_crossover=auto_discovery_crossover,
            auto_discovery_offer_interval=auto_discovery_offer_interval,
            auto_discovery_dialup_placeholder=auto_discovery_dialup_placeholder,
            encapsulation=encapsulation,
            encapsulation_address=encapsulation_address,
            encap_local_gw4=encap_local_gw4,
            encap_local_gw6=encap_local_gw6,
            encap_remote_gw4=encap_remote_gw4,
            encap_remote_gw6=encap_remote_gw6,
            vni=vni,
            nattraversal=nattraversal,
            esn=esn,
            fragmentation_mtu=fragmentation_mtu,
            childless_ike=childless_ike,
            azure_ad_autoconnect=azure_ad_autoconnect,
            client_resume=client_resume,
            client_resume_interval=client_resume_interval,
            rekey=rekey,
            digital_signature_auth=digital_signature_auth,
            signature_hash_alg=signature_hash_alg,
            rsa_signature_format=rsa_signature_format,
            rsa_signature_hash_override=rsa_signature_hash_override,
            enforce_unique_id=enforce_unique_id,
            cert_id_validation=cert_id_validation,
            fec_egress=fec_egress,
            fec_send_timeout=fec_send_timeout,
            fec_base=fec_base,
            fec_codec=fec_codec,
            fec_redundant=fec_redundant,
            fec_ingress=fec_ingress,
            fec_receive_timeout=fec_receive_timeout,
            fec_health_check=fec_health_check,
            fec_mapping_profile=fec_mapping_profile,
            network_overlay=network_overlay,
            network_id=network_id,
            dev_id_notification=dev_id_notification,
            dev_id=dev_id,
            loopback_asymroute=loopback_asymroute,
            link_cost=link_cost,
            kms=kms,
            exchange_fgt_device_id=exchange_fgt_device_id,
            ipv6_auto_linklocal=ipv6_auto_linklocal,
            ems_sn_check=ems_sn_check,
            cert_trust_store=cert_trust_store,
            qkd=qkd,
            qkd_hybrid=qkd_hybrid,
            qkd_profile=qkd_profile,
            transport=transport,
            fortinet_esp=fortinet_esp,
            auto_transport_threshold=auto_transport_threshold,
            remote_gw_match=remote_gw_match,
            remote_gw_subnet=remote_gw_subnet,
            remote_gw_start_ip=remote_gw_start_ip,
            remote_gw_end_ip=remote_gw_end_ip,
            remote_gw_country=remote_gw_country,
            remote_gw_ztna_tags=remote_gw_ztna_tags,
            remote_gw6_match=remote_gw6_match,
            remote_gw6_subnet=remote_gw6_subnet,
            remote_gw6_start_ip=remote_gw6_start_ip,
            remote_gw6_end_ip=remote_gw6_end_ip,
            remote_gw6_country=remote_gw6_country,
            cert_peer_username_validation=cert_peer_username_validation,
            cert_peer_username_strip=cert_peer_username_strip,
            data=payload_dict,
        )

        # Check for deprecated fields and warn users
        from ._helpers.phase1_interface import DEPRECATED_FIELDS
        if DEPRECATED_FIELDS:
            from hfortix_core import check_deprecated_fields
            check_deprecated_fields(
                payload=payload_data,
                deprecated_fields=DEPRECATED_FIELDS,
                endpoint="cmdb/vpn/ipsec/phase1_interface",
            )

        endpoint = "/vpn.ipsec/phase1-interface"
        
        # Add explicit query parameters for POST
        params: dict[str, Any] = {}
        if q_action is not None:
            params["action"] = q_action
        if q_nkey is not None:
            params["nkey"] = q_nkey
        if q_scope is not None:
            params["scope"] = q_scope
        
        return self._client.post(
            "cmdb", endpoint, data=payload_data, params=params, vdom=vdom        )

    # ========================================================================
    # DELETE Method
    # Type hints provided by CRUDEndpoint protocol (no local @overload needed)
    # ========================================================================
    
    def delete(
        self,
        name: str | None = None,
        q_scope: str | None = None,
        vdom: str | bool | None = None,
        error_mode: Literal["raise", "return", "print"] | None = None,
        error_format: Literal["detailed", "simple", "code_only"] | None = None,
    ):  # type: ignore[no-untyped-def]
        """
        Delete vpn/ipsec/phase1_interface object.

        Configure VPN remote gateway.

        Args:
            name: Primary key identifier
            vdom: Virtual domain name
            error_mode: Override client-level error_mode. "raise" raises exceptions, "return" returns error dict, "print" prints errors.
            error_format: Override client-level error_format. "detailed" provides full context, "simple" is concise, "code_only" returns just status code.

        Returns:
            FortiObject instance. Use .dict, .json, or .raw to access as dictionary

        Raises:
            ValueError: If name is not provided

        Examples:
            >>> # Delete specific object
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.delete(name=1)
            
            >>> # Check for errors
            >>> if result.get('status') != 'success':
            ...     print(f"Delete failed: {result.get('error')}")

        See Also:
            - exists(): Check if object exists before deleting
            - get(): Retrieve object to verify it exists
        """
        if not name:
            raise ValueError("name is required for DELETE")
        endpoint = "/vpn.ipsec/phase1-interface/" + quote_path_param(name)

        # Add explicit query parameters for DELETE
        params: dict[str, Any] = {}
        if q_scope is not None:
            params["scope"] = q_scope
        
        return self._client.delete(
            "cmdb", endpoint, params=params, vdom=vdom        )

    def exists(
        self,
        name: str,
        vdom: str | bool | None = None,
    ) -> Union[bool, Coroutine[Any, Any, bool]]:
        """
        Check if vpn/ipsec/phase1_interface object exists.

        Verifies whether an object exists by attempting to retrieve it and checking the response status.

        Args:
            name: Primary key identifier
            vdom: Virtual domain name

        Returns:
            True if object exists, False otherwise

        Examples:
            >>> # Check if object exists before operations
            >>> if fgt.api.cmdb.vpn_ipsec_phase1_interface.exists(name=1):
            ...     print("Object exists")
            ... else:
            ...     print("Object not found")
            
            >>> # Conditional delete
            >>> if fgt.api.cmdb.vpn_ipsec_phase1_interface.exists(name=1):
            ...     fgt.api.cmdb.vpn_ipsec_phase1_interface.delete(name=1)

        See Also:
            - get(): Retrieve full object data
            - set(): Create or update automatically based on existence
        """
        # Use direct request with silent error handling to avoid logging 404s
        # This is expected behavior for exists() - 404 just means "doesn't exist"
        endpoint = "/vpn.ipsec/phase1-interface"
        endpoint = f"{endpoint}/{quote_path_param(name)}"
        
        # Make request with silent=True to suppress 404 error logging
        # (404 is expected when checking existence - it just means "doesn't exist")
        # Use _wrapped_client to access the underlying HTTPClient directly
        # (self._client is ResponseProcessingClient, _wrapped_client is HTTPClient)
        try:
            result = self._client._wrapped_client.get(
                "cmdb",
                endpoint,
                params=None,
                vdom=vdom,
                raw_json=True,
                silent=True,
            )
            
            if isinstance(result, dict):
                # Synchronous response - check status
                return result.get("status") == "success"
            else:
                # Asynchronous response
                async def _check() -> bool:
                    r = await result
                    return r.get("status") == "success"
                return _check()
        except Exception:
            # Any error (404, network, etc.) means we can't confirm existence
            return False


    def set(
        self,
        payload_dict: dict[str, Any] | None = None,
        name: str | None = None,
        type: Literal["static", "dynamic", "ddns"] | None = None,
        interface: str | None = None,
        ip_version: Literal["4", "6"] | None = None,
        ike_version: Literal["1", "2"] | None = None,
        local_gw: str | None = None,
        local_gw6: str | None = None,
        remote_gw: str | None = None,
        remote_gw6: str | None = None,
        remotegw_ddns: str | None = None,
        keylife: int | None = None,
        certificate: str | list[str] | list[dict[str, Any]] | None = None,
        authmethod: Literal["psk", "signature"] | None = None,
        authmethod_remote: Literal["psk", "signature"] | None = None,
        mode: Literal["aggressive", "main"] | None = None,
        peertype: Literal["any", "one", "dialup", "peer", "peergrp"] | None = None,
        peerid: str | None = None,
        default_gw: str | None = None,
        default_gw_priority: int | None = None,
        usrgrp: str | None = None,
        peer: str | None = None,
        peergrp: str | None = None,
        monitor: str | list[str] | list[dict[str, Any]] | None = None,
        monitor_min: int | None = None,
        monitor_hold_down_type: Literal["immediate", "delay", "time"] | None = None,
        monitor_hold_down_delay: int | None = None,
        monitor_hold_down_weekday: Literal["everyday", "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"] | None = None,
        monitor_hold_down_time: str | None = None,
        net_device: Literal["enable", "disable"] | None = None,
        passive_mode: Literal["enable", "disable"] | None = None,
        exchange_interface_ip: Literal["enable", "disable"] | None = None,
        exchange_ip_addr4: str | None = None,
        exchange_ip_addr6: str | None = None,
        aggregate_member: Literal["enable", "disable"] | None = None,
        aggregate_weight: int | None = None,
        packet_redistribution: Literal["enable", "disable"] | None = None,
        peer_egress_shaping: Literal["enable", "disable"] | None = None,
        peer_egress_shaping_value: int | None = None,
        mode_cfg: Literal["disable", "enable"] | None = None,
        mode_cfg_allow_client_selector: Literal["disable", "enable"] | None = None,
        assign_ip: Literal["disable", "enable"] | None = None,
        assign_ip_from: Literal["range", "usrgrp", "dhcp", "name"] | None = None,
        ipv4_start_ip: str | None = None,
        ipv4_end_ip: str | None = None,
        ipv4_netmask: str | None = None,
        dhcp_ra_giaddr: str | None = None,
        dhcp6_ra_linkaddr: str | None = None,
        dns_mode: Literal["manual", "auto"] | None = None,
        ipv4_dns_server1: str | None = None,
        ipv4_dns_server2: str | None = None,
        ipv4_dns_server3: str | None = None,
        internal_domain_list: str | list[str] | list[dict[str, Any]] | None = None,
        dns_suffix_search: str | list[str] | list[dict[str, Any]] | None = None,
        ipv4_wins_server1: str | None = None,
        ipv4_wins_server2: str | None = None,
        ipv4_exclude_range: str | list[str] | list[dict[str, Any]] | None = None,
        ipv4_split_include: str | None = None,
        split_include_service: str | None = None,
        ipv4_name: str | None = None,
        ipv6_start_ip: str | None = None,
        ipv6_end_ip: str | None = None,
        ipv6_prefix: int | None = None,
        ipv6_dns_server1: str | None = None,
        ipv6_dns_server2: str | None = None,
        ipv6_dns_server3: str | None = None,
        ipv6_exclude_range: str | list[str] | list[dict[str, Any]] | None = None,
        ipv6_split_include: str | None = None,
        ipv6_name: str | None = None,
        ip_delay_interval: int | None = None,
        unity_support: Literal["disable", "enable"] | None = None,
        domain: str | None = None,
        banner: str | None = None,
        include_local_lan: Literal["disable", "enable"] | None = None,
        ipv4_split_exclude: str | None = None,
        ipv6_split_exclude: str | None = None,
        save_password: Literal["disable", "enable"] | None = None,
        client_auto_negotiate: Literal["disable", "enable"] | None = None,
        client_keep_alive: Literal["disable", "enable"] | None = None,
        backup_gateway: str | list[str] | list[dict[str, Any]] | None = None,
        proposal: Literal["des-md5", "des-sha1", "des-sha256", "des-sha384", "des-sha512", "3des-md5", "3des-sha1", "3des-sha256", "3des-sha384", "3des-sha512", "aes128-md5", "aes128-sha1", "aes128-sha256", "aes128-sha384", "aes128-sha512", "aes128gcm-prfsha1", "aes128gcm-prfsha256", "aes128gcm-prfsha384", "aes128gcm-prfsha512", "aes192-md5", "aes192-sha1", "aes192-sha256", "aes192-sha384", "aes192-sha512", "aes256-md5", "aes256-sha1", "aes256-sha256", "aes256-sha384", "aes256-sha512", "aes256gcm-prfsha1", "aes256gcm-prfsha256", "aes256gcm-prfsha384", "aes256gcm-prfsha512", "chacha20poly1305-prfsha1", "chacha20poly1305-prfsha256", "chacha20poly1305-prfsha384", "chacha20poly1305-prfsha512", "aria128-md5", "aria128-sha1", "aria128-sha256", "aria128-sha384", "aria128-sha512", "aria192-md5", "aria192-sha1", "aria192-sha256", "aria192-sha384", "aria192-sha512", "aria256-md5", "aria256-sha1", "aria256-sha256", "aria256-sha384", "aria256-sha512", "seed-md5", "seed-sha1", "seed-sha256", "seed-sha384", "seed-sha512"] | list[str] | list[dict[str, Any]] | None = None,
        add_route: Literal["disable", "enable"] | None = None,
        add_gw_route: Literal["enable", "disable"] | None = None,
        psksecret: Any | None = None,
        psksecret_remote: Any | None = None,
        keepalive: int | None = None,
        distance: int | None = None,
        priority: int | None = None,
        localid: str | None = None,
        localid_type: Literal["auto", "fqdn", "user-fqdn", "keyid", "address", "asn1dn"] | None = None,
        auto_negotiate: Literal["enable", "disable"] | None = None,
        negotiate_timeout: int | None = None,
        fragmentation: Literal["enable", "disable"] | None = None,
        ip_fragmentation: Literal["pre-encapsulation", "post-encapsulation"] | None = None,
        dpd: Literal["disable", "on-idle", "on-demand"] | None = None,
        dpd_retrycount: int | None = None,
        dpd_retryinterval: str | None = None,
        comments: str | None = None,
        npu_offload: Literal["enable", "disable"] | None = None,
        send_cert_chain: Literal["enable", "disable"] | None = None,
        dhgrp: Literal["1", "2", "5", "14", "15", "16", "17", "18", "19", "20", "21", "27", "28", "29", "30", "31", "32"] | list[str] | list[dict[str, Any]] | None = None,
        addke1: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | list[dict[str, Any]] | None = None,
        addke2: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | list[dict[str, Any]] | None = None,
        addke3: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | list[dict[str, Any]] | None = None,
        addke4: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | list[dict[str, Any]] | None = None,
        addke5: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | list[dict[str, Any]] | None = None,
        addke6: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | list[dict[str, Any]] | None = None,
        addke7: Literal["0", "35", "36", "37", "1080", "1081", "1082", "1083", "1084", "1085", "1089", "1090", "1091", "1092", "1093", "1094"] | list[str] | list[dict[str, Any]] | None = None,
        suite_b: Literal["disable", "suite-b-gcm-128", "suite-b-gcm-256"] | None = None,
        eap: Literal["enable", "disable"] | None = None,
        eap_identity: Literal["use-id-payload", "send-request"] | None = None,
        eap_exclude_peergrp: str | None = None,
        eap_cert_auth: Literal["enable", "disable"] | None = None,
        acct_verify: Literal["enable", "disable"] | None = None,
        ppk: Literal["disable", "allow", "require"] | None = None,
        ppk_secret: Any | None = None,
        ppk_identity: str | None = None,
        wizard_type: Literal["custom", "dialup-forticlient", "dialup-ios", "dialup-android", "dialup-windows", "dialup-cisco", "static-fortigate", "dialup-fortigate", "static-cisco", "dialup-cisco-fw", "simplified-static-fortigate", "hub-fortigate-auto-discovery", "spoke-fortigate-auto-discovery", "fabric-overlay-orchestrator"] | None = None,
        xauthtype: Literal["disable", "client", "pap", "chap", "auto"] | None = None,
        reauth: Literal["disable", "enable"] | None = None,
        authusr: str | None = None,
        authpasswd: Any | None = None,
        group_authentication: Literal["enable", "disable"] | None = None,
        group_authentication_secret: Any | None = None,
        authusrgrp: str | None = None,
        mesh_selector_type: Literal["disable", "subnet", "host"] | None = None,
        idle_timeout: Literal["enable", "disable"] | None = None,
        shared_idle_timeout: Literal["enable", "disable"] | None = None,
        idle_timeoutinterval: int | None = None,
        ha_sync_esp_seqno: Literal["enable", "disable"] | None = None,
        fgsp_sync: Literal["enable", "disable"] | None = None,
        inbound_dscp_copy: Literal["enable", "disable"] | None = None,
        auto_discovery_sender: Literal["enable", "disable"] | None = None,
        auto_discovery_receiver: Literal["enable", "disable"] | None = None,
        auto_discovery_forwarder: Literal["enable", "disable"] | None = None,
        auto_discovery_psk: Literal["enable", "disable"] | None = None,
        auto_discovery_shortcuts: Literal["independent", "dependent"] | None = None,
        auto_discovery_crossover: Literal["allow", "block"] | None = None,
        auto_discovery_offer_interval: int | None = None,
        auto_discovery_dialup_placeholder: Literal["disable", "enable"] | None = None,
        encapsulation: Literal["none", "gre", "vxlan", "vpn-id-ipip"] | None = None,
        encapsulation_address: Literal["ike", "ipv4", "ipv6"] | None = None,
        encap_local_gw4: str | None = None,
        encap_local_gw6: str | None = None,
        encap_remote_gw4: str | None = None,
        encap_remote_gw6: str | None = None,
        vni: int | None = None,
        nattraversal: Literal["enable", "disable", "forced"] | None = None,
        esn: Literal["require", "allow", "disable"] | None = None,
        fragmentation_mtu: int | None = None,
        childless_ike: Literal["enable", "disable"] | None = None,
        azure_ad_autoconnect: Literal["enable", "disable"] | None = None,
        client_resume: Literal["enable", "disable"] | None = None,
        client_resume_interval: int | None = None,
        rekey: Literal["enable", "disable"] | None = None,
        digital_signature_auth: Literal["enable", "disable"] | None = None,
        signature_hash_alg: Literal["sha1", "sha2-256", "sha2-384", "sha2-512"] | list[str] | list[dict[str, Any]] | None = None,
        rsa_signature_format: Literal["pkcs1", "pss"] | None = None,
        rsa_signature_hash_override: Literal["enable", "disable"] | None = None,
        enforce_unique_id: Literal["disable", "keep-new", "keep-old"] | None = None,
        cert_id_validation: Literal["enable", "disable"] | None = None,
        fec_egress: Literal["enable", "disable"] | None = None,
        fec_send_timeout: int | None = None,
        fec_base: int | None = None,
        fec_codec: Literal["rs", "xor"] | None = None,
        fec_redundant: int | None = None,
        fec_ingress: Literal["enable", "disable"] | None = None,
        fec_receive_timeout: int | None = None,
        fec_health_check: str | None = None,
        fec_mapping_profile: str | None = None,
        network_overlay: Literal["disable", "enable"] | None = None,
        network_id: int | None = None,
        dev_id_notification: Literal["disable", "enable"] | None = None,
        dev_id: str | None = None,
        loopback_asymroute: Literal["enable", "disable"] | None = None,
        link_cost: int | None = None,
        kms: str | None = None,
        exchange_fgt_device_id: Literal["enable", "disable"] | None = None,
        ipv6_auto_linklocal: Literal["enable", "disable"] | None = None,
        ems_sn_check: Literal["enable", "disable"] | None = None,
        cert_trust_store: Literal["local", "ems"] | None = None,
        qkd: Literal["disable", "allow", "require"] | None = None,
        qkd_hybrid: Literal["disable", "allow", "require"] | None = None,
        qkd_profile: str | None = None,
        transport: Literal["udp", "auto", "tcp"] | None = None,
        fortinet_esp: Literal["enable", "disable"] | None = None,
        auto_transport_threshold: int | None = None,
        remote_gw_match: Literal["any", "ipmask", "iprange", "geography", "ztna"] | None = None,
        remote_gw_subnet: Any | None = None,
        remote_gw_start_ip: str | None = None,
        remote_gw_end_ip: str | None = None,
        remote_gw_country: str | None = None,
        remote_gw_ztna_tags: str | list[str] | list[dict[str, Any]] | None = None,
        remote_gw6_match: Literal["any", "ipprefix", "iprange", "geography"] | None = None,
        remote_gw6_subnet: str | None = None,
        remote_gw6_start_ip: str | None = None,
        remote_gw6_end_ip: str | None = None,
        remote_gw6_country: str | None = None,
        cert_peer_username_validation: Literal["none", "othername", "rfc822name", "cn"] | None = None,
        cert_peer_username_strip: Literal["disable", "enable"] | None = None,
        vdom: str | bool | None = None,
        error_mode: Literal["raise", "return", "print"] | None = None,
        error_format: Literal["detailed", "simple", "code_only"] | None = None,
        **kwargs: Any,
    ) -> Union[dict[str, Any], Coroutine[Any, Any, dict[str, Any]]]:
        """
        Create or update vpn/ipsec/phase1_interface object (intelligent operation).

        Automatically determines whether to create (POST) or update (PUT) based on
        whether the resource exists. Requires the primary key (name) in the payload.

        Args:
            payload_dict: Resource data including name (primary key)
            name: Field name
            type: Field type
            interface: Field interface
            ip_version: Field ip-version
            ike_version: Field ike-version
            local_gw: Field local-gw
            local_gw6: Field local-gw6
            remote_gw: Field remote-gw
            remote_gw6: Field remote-gw6
            remotegw_ddns: Field remotegw-ddns
            keylife: Field keylife
            certificate: Field certificate
            authmethod: Field authmethod
            authmethod_remote: Field authmethod-remote
            mode: Field mode
            peertype: Field peertype
            peerid: Field peerid
            default_gw: Field default-gw
            default_gw_priority: Field default-gw-priority
            usrgrp: Field usrgrp
            peer: Field peer
            peergrp: Field peergrp
            monitor: Field monitor
            monitor_min: Field monitor-min
            monitor_hold_down_type: Field monitor-hold-down-type
            monitor_hold_down_delay: Field monitor-hold-down-delay
            monitor_hold_down_weekday: Field monitor-hold-down-weekday
            monitor_hold_down_time: Field monitor-hold-down-time
            net_device: Field net-device
            passive_mode: Field passive-mode
            exchange_interface_ip: Field exchange-interface-ip
            exchange_ip_addr4: Field exchange-ip-addr4
            exchange_ip_addr6: Field exchange-ip-addr6
            aggregate_member: Field aggregate-member
            aggregate_weight: Field aggregate-weight
            packet_redistribution: Field packet-redistribution
            peer_egress_shaping: Field peer-egress-shaping
            peer_egress_shaping_value: Field peer-egress-shaping-value
            mode_cfg: Field mode-cfg
            mode_cfg_allow_client_selector: Field mode-cfg-allow-client-selector
            assign_ip: Field assign-ip
            assign_ip_from: Field assign-ip-from
            ipv4_start_ip: Field ipv4-start-ip
            ipv4_end_ip: Field ipv4-end-ip
            ipv4_netmask: Field ipv4-netmask
            dhcp_ra_giaddr: Field dhcp-ra-giaddr
            dhcp6_ra_linkaddr: Field dhcp6-ra-linkaddr
            dns_mode: Field dns-mode
            ipv4_dns_server1: Field ipv4-dns-server1
            ipv4_dns_server2: Field ipv4-dns-server2
            ipv4_dns_server3: Field ipv4-dns-server3
            internal_domain_list: Field internal-domain-list
            dns_suffix_search: Field dns-suffix-search
            ipv4_wins_server1: Field ipv4-wins-server1
            ipv4_wins_server2: Field ipv4-wins-server2
            ipv4_exclude_range: Field ipv4-exclude-range
            ipv4_split_include: Field ipv4-split-include
            split_include_service: Field split-include-service
            ipv4_name: Field ipv4-name
            ipv6_start_ip: Field ipv6-start-ip
            ipv6_end_ip: Field ipv6-end-ip
            ipv6_prefix: Field ipv6-prefix
            ipv6_dns_server1: Field ipv6-dns-server1
            ipv6_dns_server2: Field ipv6-dns-server2
            ipv6_dns_server3: Field ipv6-dns-server3
            ipv6_exclude_range: Field ipv6-exclude-range
            ipv6_split_include: Field ipv6-split-include
            ipv6_name: Field ipv6-name
            ip_delay_interval: Field ip-delay-interval
            unity_support: Field unity-support
            domain: Field domain
            banner: Field banner
            include_local_lan: Field include-local-lan
            ipv4_split_exclude: Field ipv4-split-exclude
            ipv6_split_exclude: Field ipv6-split-exclude
            save_password: Field save-password
            client_auto_negotiate: Field client-auto-negotiate
            client_keep_alive: Field client-keep-alive
            backup_gateway: Field backup-gateway
            proposal: Field proposal
            add_route: Field add-route
            add_gw_route: Field add-gw-route
            psksecret: Field psksecret
            psksecret_remote: Field psksecret-remote
            keepalive: Field keepalive
            distance: Field distance
            priority: Field priority
            localid: Field localid
            localid_type: Field localid-type
            auto_negotiate: Field auto-negotiate
            negotiate_timeout: Field negotiate-timeout
            fragmentation: Field fragmentation
            ip_fragmentation: Field ip-fragmentation
            dpd: Field dpd
            dpd_retrycount: Field dpd-retrycount
            dpd_retryinterval: Field dpd-retryinterval
            comments: Field comments
            npu_offload: Field npu-offload
            send_cert_chain: Field send-cert-chain
            dhgrp: Field dhgrp
            addke1: Field addke1
            addke2: Field addke2
            addke3: Field addke3
            addke4: Field addke4
            addke5: Field addke5
            addke6: Field addke6
            addke7: Field addke7
            suite_b: Field suite-b
            eap: Field eap
            eap_identity: Field eap-identity
            eap_exclude_peergrp: Field eap-exclude-peergrp
            eap_cert_auth: Field eap-cert-auth
            acct_verify: Field acct-verify
            ppk: Field ppk
            ppk_secret: Field ppk-secret
            ppk_identity: Field ppk-identity
            wizard_type: Field wizard-type
            xauthtype: Field xauthtype
            reauth: Field reauth
            authusr: Field authusr
            authpasswd: Field authpasswd
            group_authentication: Field group-authentication
            group_authentication_secret: Field group-authentication-secret
            authusrgrp: Field authusrgrp
            mesh_selector_type: Field mesh-selector-type
            idle_timeout: Field idle-timeout
            shared_idle_timeout: Field shared-idle-timeout
            idle_timeoutinterval: Field idle-timeoutinterval
            ha_sync_esp_seqno: Field ha-sync-esp-seqno
            fgsp_sync: Field fgsp-sync
            inbound_dscp_copy: Field inbound-dscp-copy
            auto_discovery_sender: Field auto-discovery-sender
            auto_discovery_receiver: Field auto-discovery-receiver
            auto_discovery_forwarder: Field auto-discovery-forwarder
            auto_discovery_psk: Field auto-discovery-psk
            auto_discovery_shortcuts: Field auto-discovery-shortcuts
            auto_discovery_crossover: Field auto-discovery-crossover
            auto_discovery_offer_interval: Field auto-discovery-offer-interval
            auto_discovery_dialup_placeholder: Field auto-discovery-dialup-placeholder
            encapsulation: Field encapsulation
            encapsulation_address: Field encapsulation-address
            encap_local_gw4: Field encap-local-gw4
            encap_local_gw6: Field encap-local-gw6
            encap_remote_gw4: Field encap-remote-gw4
            encap_remote_gw6: Field encap-remote-gw6
            vni: Field vni
            nattraversal: Field nattraversal
            esn: Field esn
            fragmentation_mtu: Field fragmentation-mtu
            childless_ike: Field childless-ike
            azure_ad_autoconnect: Field azure-ad-autoconnect
            client_resume: Field client-resume
            client_resume_interval: Field client-resume-interval
            rekey: Field rekey
            digital_signature_auth: Field digital-signature-auth
            signature_hash_alg: Field signature-hash-alg
            rsa_signature_format: Field rsa-signature-format
            rsa_signature_hash_override: Field rsa-signature-hash-override
            enforce_unique_id: Field enforce-unique-id
            cert_id_validation: Field cert-id-validation
            fec_egress: Field fec-egress
            fec_send_timeout: Field fec-send-timeout
            fec_base: Field fec-base
            fec_codec: Field fec-codec
            fec_redundant: Field fec-redundant
            fec_ingress: Field fec-ingress
            fec_receive_timeout: Field fec-receive-timeout
            fec_health_check: Field fec-health-check
            fec_mapping_profile: Field fec-mapping-profile
            network_overlay: Field network-overlay
            network_id: Field network-id
            dev_id_notification: Field dev-id-notification
            dev_id: Field dev-id
            loopback_asymroute: Field loopback-asymroute
            link_cost: Field link-cost
            kms: Field kms
            exchange_fgt_device_id: Field exchange-fgt-device-id
            ipv6_auto_linklocal: Field ipv6-auto-linklocal
            ems_sn_check: Field ems-sn-check
            cert_trust_store: Field cert-trust-store
            qkd: Field qkd
            qkd_hybrid: Field qkd-hybrid
            qkd_profile: Field qkd-profile
            transport: Field transport
            fortinet_esp: Field fortinet-esp
            auto_transport_threshold: Field auto-transport-threshold
            remote_gw_match: Field remote-gw-match
            remote_gw_subnet: Field remote-gw-subnet
            remote_gw_start_ip: Field remote-gw-start-ip
            remote_gw_end_ip: Field remote-gw-end-ip
            remote_gw_country: Field remote-gw-country
            remote_gw_ztna_tags: Field remote-gw-ztna-tags
            remote_gw6_match: Field remote-gw6-match
            remote_gw6_subnet: Field remote-gw6-subnet
            remote_gw6_start_ip: Field remote-gw6-start-ip
            remote_gw6_end_ip: Field remote-gw6-end-ip
            remote_gw6_country: Field remote-gw6-country
            cert_peer_username_validation: Field cert-peer-username-validation
            cert_peer_username_strip: Field cert-peer-username-strip
            vdom: Virtual domain name
            **kwargs: Additional parameters passed to PUT or POST

        Returns:
            FortiObject instance. Use .dict, .json, or .raw to access as dictionary

        Raises:
            ValueError: If name is missing from payload

        Examples:
            >>> # Intelligent create or update using field parameters
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.set(
            ...     name=1,
            ...     # ... other fields
            ... )
            
            >>> # Or using payload dict
            >>> payload = {
            ...     "name": 1,
            ...     "field1": "value1",
            ...     "field2": "value2",
            ... }
            >>> result = fgt.api.cmdb.vpn_ipsec_phase1_interface.set(payload_dict=payload)
            >>> # Will POST if object doesn't exist, PUT if it does
            
            >>> # Idempotent configuration
            >>> for obj_data in configuration_list:
            ...     fgt.api.cmdb.vpn_ipsec_phase1_interface.set(payload_dict=obj_data)
            >>> # Safely applies configuration regardless of current state

        Note:
            This method internally calls exists() then either post() or put().
            For performance-critical code with known state, call post() or put() directly.

        See Also:
            - post(): Create new object
            - put(): Update existing object
            - exists(): Check existence manually
        """
        # Apply normalization for table fields (supports flexible input formats)
        if certificate is not None:
            certificate = normalize_table_field(
                certificate,
                mkey="name",
                required_fields=['name'],
                field_name="certificate",
                example="[{'name': 'value'}]",
            )
        if monitor is not None:
            monitor = normalize_table_field(
                monitor,
                mkey="name",
                required_fields=['name'],
                field_name="monitor",
                example="[{'name': 'value'}]",
            )
        if internal_domain_list is not None:
            internal_domain_list = normalize_table_field(
                internal_domain_list,
                mkey="domain-name",
                required_fields=['domain-name'],
                field_name="internal_domain_list",
                example="[{'domain-name': 'value'}]",
            )
        if dns_suffix_search is not None:
            dns_suffix_search = normalize_table_field(
                dns_suffix_search,
                mkey="dns-suffix",
                required_fields=['dns-suffix'],
                field_name="dns_suffix_search",
                example="[{'dns-suffix': 'value'}]",
            )
        if ipv4_exclude_range is not None:
            ipv4_exclude_range = normalize_table_field(
                ipv4_exclude_range,
                mkey="id",
                required_fields=['id', 'start-ip', 'end-ip'],
                field_name="ipv4_exclude_range",
                example="[{'id': 1, 'start-ip': '192.168.1.10', 'end-ip': '192.168.1.10'}]",
            )
        if ipv6_exclude_range is not None:
            ipv6_exclude_range = normalize_table_field(
                ipv6_exclude_range,
                mkey="id",
                required_fields=['id', 'start-ip', 'end-ip'],
                field_name="ipv6_exclude_range",
                example="[{'id': 1, 'start-ip': 'value', 'end-ip': 'value'}]",
            )
        if backup_gateway is not None:
            backup_gateway = normalize_table_field(
                backup_gateway,
                mkey="address",
                required_fields=['address'],
                field_name="backup_gateway",
                example="[{'address': 'value'}]",
            )
        if remote_gw_ztna_tags is not None:
            remote_gw_ztna_tags = normalize_table_field(
                remote_gw_ztna_tags,
                mkey="name",
                required_fields=['name'],
                field_name="remote_gw_ztna_tags",
                example="[{'name': 'value'}]",
            )
        
        # Apply normalization for multi-value option fields (space-separated strings)
        
        # Build payload using helper function
        # Note: auto_normalize=False because this endpoint has unitary fields
        # (like 'interface') that would be incorrectly converted to list format
        payload_data = build_api_payload(
            auto_normalize=False,
            name=name,
            type=type,
            interface=interface,
            ip_version=ip_version,
            ike_version=ike_version,
            local_gw=local_gw,
            local_gw6=local_gw6,
            remote_gw=remote_gw,
            remote_gw6=remote_gw6,
            remotegw_ddns=remotegw_ddns,
            keylife=keylife,
            certificate=certificate,
            authmethod=authmethod,
            authmethod_remote=authmethod_remote,
            mode=mode,
            peertype=peertype,
            peerid=peerid,
            default_gw=default_gw,
            default_gw_priority=default_gw_priority,
            usrgrp=usrgrp,
            peer=peer,
            peergrp=peergrp,
            monitor=monitor,
            monitor_min=monitor_min,
            monitor_hold_down_type=monitor_hold_down_type,
            monitor_hold_down_delay=monitor_hold_down_delay,
            monitor_hold_down_weekday=monitor_hold_down_weekday,
            monitor_hold_down_time=monitor_hold_down_time,
            net_device=net_device,
            passive_mode=passive_mode,
            exchange_interface_ip=exchange_interface_ip,
            exchange_ip_addr4=exchange_ip_addr4,
            exchange_ip_addr6=exchange_ip_addr6,
            aggregate_member=aggregate_member,
            aggregate_weight=aggregate_weight,
            packet_redistribution=packet_redistribution,
            peer_egress_shaping=peer_egress_shaping,
            peer_egress_shaping_value=peer_egress_shaping_value,
            mode_cfg=mode_cfg,
            mode_cfg_allow_client_selector=mode_cfg_allow_client_selector,
            assign_ip=assign_ip,
            assign_ip_from=assign_ip_from,
            ipv4_start_ip=ipv4_start_ip,
            ipv4_end_ip=ipv4_end_ip,
            ipv4_netmask=ipv4_netmask,
            dhcp_ra_giaddr=dhcp_ra_giaddr,
            dhcp6_ra_linkaddr=dhcp6_ra_linkaddr,
            dns_mode=dns_mode,
            ipv4_dns_server1=ipv4_dns_server1,
            ipv4_dns_server2=ipv4_dns_server2,
            ipv4_dns_server3=ipv4_dns_server3,
            internal_domain_list=internal_domain_list,
            dns_suffix_search=dns_suffix_search,
            ipv4_wins_server1=ipv4_wins_server1,
            ipv4_wins_server2=ipv4_wins_server2,
            ipv4_exclude_range=ipv4_exclude_range,
            ipv4_split_include=ipv4_split_include,
            split_include_service=split_include_service,
            ipv4_name=ipv4_name,
            ipv6_start_ip=ipv6_start_ip,
            ipv6_end_ip=ipv6_end_ip,
            ipv6_prefix=ipv6_prefix,
            ipv6_dns_server1=ipv6_dns_server1,
            ipv6_dns_server2=ipv6_dns_server2,
            ipv6_dns_server3=ipv6_dns_server3,
            ipv6_exclude_range=ipv6_exclude_range,
            ipv6_split_include=ipv6_split_include,
            ipv6_name=ipv6_name,
            ip_delay_interval=ip_delay_interval,
            unity_support=unity_support,
            domain=domain,
            banner=banner,
            include_local_lan=include_local_lan,
            ipv4_split_exclude=ipv4_split_exclude,
            ipv6_split_exclude=ipv6_split_exclude,
            save_password=save_password,
            client_auto_negotiate=client_auto_negotiate,
            client_keep_alive=client_keep_alive,
            backup_gateway=backup_gateway,
            proposal=proposal,
            add_route=add_route,
            add_gw_route=add_gw_route,
            psksecret=psksecret,
            psksecret_remote=psksecret_remote,
            keepalive=keepalive,
            distance=distance,
            priority=priority,
            localid=localid,
            localid_type=localid_type,
            auto_negotiate=auto_negotiate,
            negotiate_timeout=negotiate_timeout,
            fragmentation=fragmentation,
            ip_fragmentation=ip_fragmentation,
            dpd=dpd,
            dpd_retrycount=dpd_retrycount,
            dpd_retryinterval=dpd_retryinterval,
            comments=comments,
            npu_offload=npu_offload,
            send_cert_chain=send_cert_chain,
            dhgrp=dhgrp,
            addke1=addke1,
            addke2=addke2,
            addke3=addke3,
            addke4=addke4,
            addke5=addke5,
            addke6=addke6,
            addke7=addke7,
            suite_b=suite_b,
            eap=eap,
            eap_identity=eap_identity,
            eap_exclude_peergrp=eap_exclude_peergrp,
            eap_cert_auth=eap_cert_auth,
            acct_verify=acct_verify,
            ppk=ppk,
            ppk_secret=ppk_secret,
            ppk_identity=ppk_identity,
            wizard_type=wizard_type,
            xauthtype=xauthtype,
            reauth=reauth,
            authusr=authusr,
            authpasswd=authpasswd,
            group_authentication=group_authentication,
            group_authentication_secret=group_authentication_secret,
            authusrgrp=authusrgrp,
            mesh_selector_type=mesh_selector_type,
            idle_timeout=idle_timeout,
            shared_idle_timeout=shared_idle_timeout,
            idle_timeoutinterval=idle_timeoutinterval,
            ha_sync_esp_seqno=ha_sync_esp_seqno,
            fgsp_sync=fgsp_sync,
            inbound_dscp_copy=inbound_dscp_copy,
            auto_discovery_sender=auto_discovery_sender,
            auto_discovery_receiver=auto_discovery_receiver,
            auto_discovery_forwarder=auto_discovery_forwarder,
            auto_discovery_psk=auto_discovery_psk,
            auto_discovery_shortcuts=auto_discovery_shortcuts,
            auto_discovery_crossover=auto_discovery_crossover,
            auto_discovery_offer_interval=auto_discovery_offer_interval,
            auto_discovery_dialup_placeholder=auto_discovery_dialup_placeholder,
            encapsulation=encapsulation,
            encapsulation_address=encapsulation_address,
            encap_local_gw4=encap_local_gw4,
            encap_local_gw6=encap_local_gw6,
            encap_remote_gw4=encap_remote_gw4,
            encap_remote_gw6=encap_remote_gw6,
            vni=vni,
            nattraversal=nattraversal,
            esn=esn,
            fragmentation_mtu=fragmentation_mtu,
            childless_ike=childless_ike,
            azure_ad_autoconnect=azure_ad_autoconnect,
            client_resume=client_resume,
            client_resume_interval=client_resume_interval,
            rekey=rekey,
            digital_signature_auth=digital_signature_auth,
            signature_hash_alg=signature_hash_alg,
            rsa_signature_format=rsa_signature_format,
            rsa_signature_hash_override=rsa_signature_hash_override,
            enforce_unique_id=enforce_unique_id,
            cert_id_validation=cert_id_validation,
            fec_egress=fec_egress,
            fec_send_timeout=fec_send_timeout,
            fec_base=fec_base,
            fec_codec=fec_codec,
            fec_redundant=fec_redundant,
            fec_ingress=fec_ingress,
            fec_receive_timeout=fec_receive_timeout,
            fec_health_check=fec_health_check,
            fec_mapping_profile=fec_mapping_profile,
            network_overlay=network_overlay,
            network_id=network_id,
            dev_id_notification=dev_id_notification,
            dev_id=dev_id,
            loopback_asymroute=loopback_asymroute,
            link_cost=link_cost,
            kms=kms,
            exchange_fgt_device_id=exchange_fgt_device_id,
            ipv6_auto_linklocal=ipv6_auto_linklocal,
            ems_sn_check=ems_sn_check,
            cert_trust_store=cert_trust_store,
            qkd=qkd,
            qkd_hybrid=qkd_hybrid,
            qkd_profile=qkd_profile,
            transport=transport,
            fortinet_esp=fortinet_esp,
            auto_transport_threshold=auto_transport_threshold,
            remote_gw_match=remote_gw_match,
            remote_gw_subnet=remote_gw_subnet,
            remote_gw_start_ip=remote_gw_start_ip,
            remote_gw_end_ip=remote_gw_end_ip,
            remote_gw_country=remote_gw_country,
            remote_gw_ztna_tags=remote_gw_ztna_tags,
            remote_gw6_match=remote_gw6_match,
            remote_gw6_subnet=remote_gw6_subnet,
            remote_gw6_start_ip=remote_gw6_start_ip,
            remote_gw6_end_ip=remote_gw6_end_ip,
            remote_gw6_country=remote_gw6_country,
            cert_peer_username_validation=cert_peer_username_validation,
            cert_peer_username_strip=cert_peer_username_strip,
            data=payload_dict,
        )
        
        mkey_value = payload_data.get("name")
        if not mkey_value:
            raise ValueError("name is required for set()")
        
        # Check if resource exists
        if self.exists(name=mkey_value, vdom=vdom):
            # Update existing resource
            return self.put(payload_dict=payload_data, vdom=vdom, **kwargs)
        else:
            # Create new resource
            return self.post(payload_dict=payload_data, vdom=vdom, **kwargs)

    # ========================================================================
    # Action: Move
    # ========================================================================
    
    def move(
        self,
        name: str,
        action: Literal["before", "after"],
        reference_name: str,
        vdom: str | bool | None = None,
        **kwargs: Any,
    ) -> Union[dict[str, Any], Coroutine[Any, Any, dict[str, Any]]]:
        """
        Move vpn/ipsec/phase1_interface object to a new position.
        
        Reorders objects by moving one before or after another.
        
        Args:
            name: Identifier of object to move
            action: Move "before" or "after" reference object
            reference_name: Identifier of reference object
            vdom: Virtual domain name
            **kwargs: Additional parameters
            
        Returns:
            API response dictionary
            
        Example:
            >>> # Move policy 100 before policy 50
            >>> fgt.api.cmdb.vpn_ipsec_phase1_interface.move(
            ...     name=100,
            ...     action="before",
            ...     reference_name=50
            ... )
        """
        return self._client.request(
            method="PUT",
            path=f"/api/v2/cmdb/vpn.ipsec/phase1-interface",
            params={
                "name": name,
                "action": "move",
                action: reference_name,
                "vdom": vdom,
                **kwargs,
            },
        )

    # ========================================================================
    # Action: Clone
    # ========================================================================
    
    def clone(
        self,
        name: str,
        new_name: str,
        vdom: str | bool | None = None,
        **kwargs: Any,
    ) -> Union[dict[str, Any], Coroutine[Any, Any, dict[str, Any]]]:
        """
        Clone vpn/ipsec/phase1_interface object.
        
        Creates a copy of an existing object with a new identifier.
        
        Args:
            name: Identifier of object to clone
            new_name: Identifier for the cloned object
            vdom: Virtual domain name
            **kwargs: Additional parameters
            
        Returns:
            API response dictionary
            
        Example:
            >>> # Clone an existing object
            >>> fgt.api.cmdb.vpn_ipsec_phase1_interface.clone(
            ...     name=1,
            ...     new_name=100
            ... )
        """
        return self._client.request(
            method="POST",
            path=f"/api/v2/cmdb/vpn.ipsec/phase1-interface",
            params={
                "name": name,
                "new_name": new_name,
                "action": "clone",
                "vdom": vdom,
                **kwargs,
            },
        )


