# coding: utf-8

"""
    Mixpeek API

    This is the Mixpeek API, providing access to various endpoints for data processing and retrieval.

    The version of the OpenAPI document: 1.3.0
    Contact: info@mixpeek.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from mixpeek.models.postgre_sql_credentials import PostgreSQLCredentials
from typing import Optional, Set
from typing_extensions import Self

class PostgreSQLConfig(BaseModel):
    """
    PostgreSQL database configuration for table-based sync and SQL queries.  Enables syncing PostgreSQL table rows as JSON objects and running SQL queries via the SQL Lookup retriever stage. Each row becomes one object, with incremental sync via watermark columns.  Authentication:     - Username/Password: Standard PostgreSQL authentication  Requirements:     - PostgreSQL 12+ recommended     - Read access to target tables     - Network connectivity to PostgreSQL server  Use Cases:     - Sync customer data tables for AI/ML pipelines     - Run SQL lookups to enrich documents in retriever pipelines     - Ingest product catalog for search/recommendations     - Process transaction logs for analytics  Example:     ```python     config = {         \"provider_type\": \"postgresql\",         \"credentials\": {             \"type\": \"username_password\",             \"username\": \"mixpeek_sync\",             \"password\": \"secure_password\",         },         \"host\": \"db.example.com\",         \"port\": 5432,         \"database\": \"production\",         \"schema\": \"public\",         \"ssl_mode\": \"require\",     }     ```
    """ # noqa: E501
    provider_type: Optional[StrictStr] = 'postgresql'
    credentials: PostgreSQLCredentials = Field(description="REQUIRED. PostgreSQL authentication credentials. Currently supports username/password authentication.")
    host: StrictStr = Field(description="REQUIRED. PostgreSQL server hostname or IP address. Examples: 'localhost', 'db.example.com', '192.168.1.100'")
    port: Optional[Annotated[int, Field(le=65535, strict=True, ge=1)]] = Field(default=5432, description="PostgreSQL server port. Default: 5432 (standard PostgreSQL port)")
    database: StrictStr = Field(description="REQUIRED. Database name to connect to. User must have CONNECT privilege on this database.")
    var_schema: Optional[StrictStr] = Field(default='public', description="Schema name for default context. Default: 'public'. User must have USAGE privilege on this schema.", alias="schema")
    ssl_mode: Optional[StrictStr] = Field(default='prefer', description="SSL/TLS connection mode. Options: 'disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full'. Default: 'prefer'. RECOMMENDED: Use 'require' or stricter for production environments.")
    incremental_column: Optional[StrictStr] = Field(default=None, description="NOT REQUIRED. Column name for incremental sync watermark. Should be a TIMESTAMP or DATE column that tracks row modifications. Common values: updated_at, modified_at, last_updated. If omitted, full table scan on every sync.")
    primary_key_columns: Optional[List[StrictStr]] = Field(default=None, description="NOT REQUIRED. Column names forming the primary key for stable object IDs. Used to generate deterministic file_id for deduplication. If omitted, uses hash of entire row content.")
    query_timeout_seconds: Optional[Annotated[int, Field(le=3600, strict=True, ge=1)]] = Field(default=300, description="Query timeout in seconds. Default: 300 seconds (5 minutes). Increase for large tables or complex queries.")
    fetch_size: Optional[Annotated[int, Field(le=10000, strict=True, ge=100)]] = Field(default=1000, description="Number of rows to fetch per batch. Higher values reduce network overhead but increase memory usage. Default: 1000 rows.")
    __properties: ClassVar[List[str]] = ["provider_type", "credentials", "host", "port", "database", "schema", "ssl_mode", "incremental_column", "primary_key_columns", "query_timeout_seconds", "fetch_size"]

    @field_validator('provider_type')
    def provider_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['postgresql']):
            raise ValueError("must be one of enum values ('postgresql')")
        return value

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of PostgreSQLConfig from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of credentials
        if self.credentials:
            _dict['credentials'] = self.credentials.to_dict()
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of PostgreSQLConfig from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "provider_type": obj.get("provider_type") if obj.get("provider_type") is not None else 'postgresql',
            "credentials": PostgreSQLCredentials.from_dict(obj["credentials"]) if obj.get("credentials") is not None else None,
            "host": obj.get("host"),
            "port": obj.get("port") if obj.get("port") is not None else 5432,
            "database": obj.get("database"),
            "schema": obj.get("schema") if obj.get("schema") is not None else 'public',
            "ssl_mode": obj.get("ssl_mode") if obj.get("ssl_mode") is not None else 'prefer',
            "incremental_column": obj.get("incremental_column"),
            "primary_key_columns": obj.get("primary_key_columns"),
            "query_timeout_seconds": obj.get("query_timeout_seconds") if obj.get("query_timeout_seconds") is not None else 300,
            "fetch_size": obj.get("fetch_size") if obj.get("fetch_size") is not None else 1000
        })
        return _obj


