# 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 typing import Dict, List, Optional

from pypaimon.common.file_io import FileIO
from pypaimon.common.identifier import Identifier
from pypaimon.schema.table_schema import TableSchema
from pypaimon.table.table import Table


# Fixed schema matching Java ObjectTable.SCHEMA
OBJECT_TABLE_FIELD_NAMES = ["path", "name", "length", "mtime", "atime", "owner"]


class ObjectTable(Table):
    """An object table refers to a directory that contains multiple objects (files).

    Object table provides metadata indexes for unstructured data objects in this
    directory, allowing users to analyze unstructured data in Object Storage.

    This is a read-only table. Write operations are not supported.
    """

    def __init__(
        self,
        file_io: FileIO,
        identifier: Identifier,
        table_schema: TableSchema,
        location: str,
        options: Optional[Dict[str, str]] = None,
        comment: Optional[str] = None,
    ):
        self.file_io = file_io
        self.identifier = identifier
        self._table_schema = table_schema
        self._location = location.rstrip("/")
        self._options = options or dict(table_schema.options)
        self.comment = comment
        self.partition_keys: List[str] = []
        self.primary_keys: List[str] = []

    def name(self) -> str:
        return self.identifier.get_table_name()

    def full_name(self) -> str:
        return self.identifier.get_full_name()

    @property
    def table_schema(self) -> TableSchema:
        return self._table_schema

    @table_schema.setter
    def table_schema(self, value: TableSchema):
        self._table_schema = value

    def location(self) -> str:
        return self._location

    def options(self) -> Dict[str, str]:
        return self._options

    def copy(self, dynamic_options: Dict[str, str]) -> "ObjectTable":
        new_options = dict(self._options)
        new_options.update(dynamic_options or {})
        return ObjectTable(
            file_io=self.file_io,
            identifier=self.identifier,
            table_schema=self._table_schema,
            location=self._location,
            options=new_options,
            comment=self.comment,
        )

    def new_read_builder(self):
        from pypaimon.table.object.object_read_builder import ObjectReadBuilder
        return ObjectReadBuilder(self)

    def new_batch_write_builder(self):
        raise NotImplementedError(
            "ObjectTable is read-only and does not support batch write."
        )

    def new_stream_read_builder(self):
        raise NotImplementedError("ObjectTable does not support stream read.")

    def new_stream_write_builder(self):
        raise NotImplementedError(
            "ObjectTable is read-only and does not support stream write."
        )

    def new_full_text_search_builder(self):
        raise NotImplementedError(
            "ObjectTable is read-only and does not support full text search."
        )

    def new_vector_search_builder(self):
        raise NotImplementedError(
            "ObjectTable is read-only and does not support vector search."
        )

    def new_hybrid_search_builder(self):
        raise NotImplementedError(
            "ObjectTable is read-only and does not support hybrid search."
        )

    def new_batch_vector_search_builder(self):
        raise NotImplementedError(
            "ObjectTable is read-only and does not support vector search."
        )
