# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from abc import ABC
from dataclasses import dataclass
from typing import Dict, List, Optional

from pypaimon.common.identifier import Identifier
from pypaimon.common.json_util import json_field
from pypaimon.function.function_change import FunctionChange
from pypaimon.function.function_definition import FunctionDefinition
from pypaimon.management.permission_access import PermissionAccess
from pypaimon.management.permission_assignment import PermissionAssignment
from pypaimon.management.permission_columns import PermissionColumns
from pypaimon.management.permission_resource import PermissionResource
from pypaimon.schema.data_types import DataField
from pypaimon.schema.schema import Schema
from pypaimon.schema.schema_change import SchemaChange
from pypaimon.snapshot.snapshot import Snapshot
from pypaimon.snapshot.snapshot_commit import PartitionStatistics
from pypaimon.table.instant import Instant


class RESTRequest(ABC):
    """RESTRequest"""


@dataclass
class CreateDatabaseRequest(RESTRequest):
    FIELD_NAME = "name"
    FIELD_OPTIONS = "options"

    name: str = json_field(FIELD_NAME)
    options: Optional[Dict[str, str]] = json_field(FIELD_OPTIONS)


@dataclass
class AlterDatabaseRequest(RESTRequest):
    FIELD_REMOVALS = "removals"
    FIELD_UPDATES = "updates"

    removals: List[str] = json_field(FIELD_REMOVALS)
    updates: Dict[str, str] = json_field(FIELD_UPDATES)


@dataclass
class RenameTableRequest(RESTRequest):
    FIELD_SOURCE = "source"
    FIELD_DESTINATION = "destination"

    source: Identifier = json_field(FIELD_SOURCE)
    destination: Identifier = json_field(FIELD_DESTINATION)


@dataclass
class CreateTableRequest(RESTRequest):
    FIELD_IDENTIFIER = "identifier"
    FIELD_SCHEMA = "schema"

    identifier: Identifier = json_field(FIELD_IDENTIFIER)
    schema: Schema = json_field(FIELD_SCHEMA)


@dataclass
class CommitTableRequest(RESTRequest):
    FIELD_TABLE_ID = "tableId"
    FIELD_BASE_SNAPSHOT_UUID = "baseSnapshotUuid"
    FIELD_SNAPSHOT = "snapshot"
    FIELD_STATISTICS = "statistics"

    table_id: Optional[str] = json_field(FIELD_TABLE_ID)
    snapshot: Snapshot = json_field(FIELD_SNAPSHOT)
    statistics: List[PartitionStatistics] = json_field(FIELD_STATISTICS)
    base_snapshot_uuid: Optional[str] = json_field(
        FIELD_BASE_SNAPSHOT_UUID, default=None
    )


@dataclass
class AlterTableRequest(RESTRequest):
    FIELD_CHANGES = "changes"

    changes: List[SchemaChange] = json_field(FIELD_CHANGES)


@dataclass
class RollbackTableRequest(RESTRequest):
    FIELD_INSTANT = "instant"
    FIELD_FROM_SNAPSHOT = "fromSnapshot"

    instant: Instant = json_field(FIELD_INSTANT)
    from_snapshot: Optional[int] = json_field(FIELD_FROM_SNAPSHOT)


@dataclass
class CreateFunctionRequest(RESTRequest):
    FIELD_NAME = "name"
    FIELD_INPUT_PARAMS = "inputParams"
    FIELD_RETURN_PARAMS = "returnParams"
    FIELD_DETERMINISTIC = "deterministic"
    FIELD_DEFINITIONS = "definitions"
    FIELD_COMMENT = "comment"
    FIELD_OPTIONS = "options"

    name: str = json_field(FIELD_NAME)
    input_params: Optional[List[DataField]] = json_field(FIELD_INPUT_PARAMS, default=None)
    return_params: Optional[List[DataField]] = json_field(FIELD_RETURN_PARAMS, default=None)
    deterministic: bool = json_field(FIELD_DETERMINISTIC, default=False)
    definitions: Optional[Dict[str, FunctionDefinition]] = json_field(FIELD_DEFINITIONS, default=None)
    comment: Optional[str] = json_field(FIELD_COMMENT, default=None)
    options: Optional[Dict[str, str]] = json_field(FIELD_OPTIONS, default=None)

    def to_dict(self) -> Dict:
        result = {
            self.FIELD_NAME: self.name,
            self.FIELD_DETERMINISTIC: self.deterministic,
        }
        if self.input_params is not None:
            result[self.FIELD_INPUT_PARAMS] = [
                p.to_dict() if hasattr(p, 'to_dict') else p for p in self.input_params
            ]
        else:
            result[self.FIELD_INPUT_PARAMS] = None
        if self.return_params is not None:
            result[self.FIELD_RETURN_PARAMS] = [
                p.to_dict() if hasattr(p, 'to_dict') else p for p in self.return_params
            ]
        else:
            result[self.FIELD_RETURN_PARAMS] = None
        if self.definitions is not None:
            result[self.FIELD_DEFINITIONS] = {
                k: v.to_dict() if hasattr(v, 'to_dict') else v
                for k, v in self.definitions.items()
            }
        else:
            result[self.FIELD_DEFINITIONS] = None
        result[self.FIELD_COMMENT] = self.comment
        result[self.FIELD_OPTIONS] = self.options
        return result


@dataclass
class AlterFunctionRequest(RESTRequest):
    FIELD_CHANGES = "changes"

    changes: List[FunctionChange] = json_field(FIELD_CHANGES)

    def to_dict(self) -> Dict:
        return {
            self.FIELD_CHANGES: [c.to_dict() for c in self.changes]
        }


# Wire DTO for ``POST /databases/{db}/tables/{tbl}/tags``. Mirrors Java
# ``CreateTagRequest`` (paimon-api/.../rest/requests/CreateTagRequest.java) — only
# three fields are serialized. ``ignoreIfExists`` is intentionally NOT included
# here; it is a client-side flag handled by ``RESTCatalog.create_tag``, not part
# of the wire format.
@dataclass
class CreateTagRequest(RESTRequest):
    FIELD_TAG_NAME = "tagName"
    FIELD_SNAPSHOT_ID = "snapshotId"
    FIELD_TIME_RETAINED = "timeRetained"

    tag_name: str = json_field(FIELD_TAG_NAME)
    snapshot_id: Optional[int] = json_field(FIELD_SNAPSHOT_ID, default=None)
    time_retained: Optional[str] = json_field(FIELD_TIME_RETAINED, default=None)


@dataclass
class CreatePartitionsRequest(RESTRequest):
    FIELD_PARTITION_SPECS = "partitionSpecs"
    FIELD_IGNORE_IF_EXISTS = "ignoreIfExists"

    partition_specs: List[Dict[str, str]] = json_field(FIELD_PARTITION_SPECS)
    ignore_if_exists: Optional[bool] = json_field(FIELD_IGNORE_IF_EXISTS, default=True)

    def __post_init__(self):
        if self.ignore_if_exists is None:
            self.ignore_if_exists = True


# Branch CRUD wire DTOs. Mirrors Java requests in
# paimon-api/.../rest/requests/.
@dataclass
class CreateBranchRequest(RESTRequest):
    FIELD_BRANCH = "branch"
    FIELD_FROM_TAG = "fromTag"

    branch: str = json_field(FIELD_BRANCH)
    from_tag: Optional[str] = json_field(FIELD_FROM_TAG, default=None)


@dataclass
class RenameBranchRequest(RESTRequest):
    FIELD_TO_BRANCH = "toBranch"

    to_branch: str = json_field(FIELD_TO_BRANCH)


@dataclass
class ForwardBranchRequest(RESTRequest):
    """Empty body request; serializes to ``{}`` per Java ForwardBranchRequest."""
    pass


class GrantPermissionRequest(RESTRequest):

    def __init__(self, assignment: PermissionAssignment):
        self._assignment = assignment

    def assignment(self) -> PermissionAssignment:
        return self._assignment

    def get_resource(self) -> PermissionResource:
        return self._assignment.get_resource()

    def get_access(self) -> str:
        return self._assignment.get_access()

    def get_principal(self) -> str:
        return self._assignment.get_principal()

    def get_columns(self) -> Optional[PermissionColumns]:
        return self._assignment.get_columns()

    def get_expire_time(self) -> Optional[str]:
        return self._assignment.get_expire_time()

    def to_dict(self) -> dict:
        return self._assignment.to_dict()

    @classmethod
    def from_dict(cls, data: dict) -> "GrantPermissionRequest":
        resource = data.get(PermissionAssignment.FIELD_RESOURCE)
        columns = data.get(PermissionAssignment.FIELD_COLUMNS)
        return cls(PermissionAssignment(
            None if resource is None else PermissionResource.from_dict(resource),
            data.get(PermissionAssignment.FIELD_ACCESS),
            data.get(PermissionAssignment.FIELD_PRINCIPAL),
            None if columns is None else PermissionColumns.from_dict(columns),
            data.get(PermissionAssignment.FIELD_EXPIRE_TIME)))


class RevokePermissionRequest(RESTRequest):

    FIELD_RESOURCE = "resource"
    FIELD_ACCESS = "access"
    FIELD_PRINCIPAL = "principal"

    def __init__(self, resource: PermissionResource, access: str, principal: str):
        self._resource = resource
        self._access = PermissionAccess.canonicalize_for(resource, access)
        self._principal = PermissionAssignment.validate_principal(principal)

    def get_resource(self) -> PermissionResource:
        return self._resource

    def get_access(self) -> str:
        return self._access

    def get_principal(self) -> str:
        return self._principal

    def to_dict(self) -> dict:
        return {
            self.FIELD_RESOURCE: self._resource.to_dict(),
            self.FIELD_ACCESS: self._access,
            self.FIELD_PRINCIPAL: self._principal,
        }

    @classmethod
    def from_dict(cls, data: dict) -> "RevokePermissionRequest":
        resource = data.get(cls.FIELD_RESOURCE)
        return cls(None if resource is None else PermissionResource.from_dict(resource),
                   data.get(cls.FIELD_ACCESS), data.get(cls.FIELD_PRINCIPAL))
