# 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 List
from urllib.parse import urlparse

import pyarrow
import pyarrow.fs as pafs

from pypaimon.table.object.object_split import ObjectSplit

from pypaimon.table.object.object_table_read import OBJECT_TABLE_ARROW_SCHEMA


def _normalize_path(path_str: str) -> str:
    """Extract the filesystem path from a URI or plain path."""
    parsed = urlparse(path_str)
    if parsed.scheme:
        return parsed.path
    return path_str


def _list_files_recursive(file_io, directory: str) -> list:
    """Recursively list all files under a directory using FileIO.

    Returns a list of (file_path, file_info) tuples.
    """
    results = []
    try:
        infos = file_io.list_status(directory)
    except Exception:
        return results

    directory_rstrip = directory.rstrip("/")
    for info in infos:
        file_name = info.path.split("/")[-1] if "/" in info.path else info.path
        full_path = info.path
        if not full_path.startswith("/") and "://" not in full_path:
            full_path = "{}/{}".format(directory_rstrip, file_name)

        if info.type == pafs.FileType.Directory:
            sub_results = _list_files_recursive(file_io, full_path)
            results.extend(sub_results)
        elif info.type == pafs.FileType.File:
            results.append((full_path, info))

    return results


def _compute_relative_path(prefix: str, file_path: str) -> str:
    """Compute relative path by removing the location prefix.

    Matches Java ObjectTableImpl.toRow() logic.
    """
    norm_prefix = _normalize_path(prefix).rstrip("/")
    norm_file = _normalize_path(file_path)

    if norm_file.startswith(norm_prefix):
        relative = norm_file[len(norm_prefix):]
        if relative.startswith("/"):
            relative = relative[1:]
        return relative

    return norm_file.split("/")[-1] if "/" in norm_file else norm_file


def to_arrow(self, splits: List[ObjectSplit]) -> pyarrow.Table:
    paths = []
    names = []
    lengths = []
    mtimes = []
    atimes = []
    owners = []

    for split in splits:
        file_entries = _list_files_recursive(split.file_io, split.location)
        for file_path, file_info in file_entries:
            if self.limit is not None and len(paths) >= self.limit:
                break

            relative_path = _compute_relative_path(split.location, file_path)
            file_name = file_path.split("/")[-1] if "/" in file_path else file_path
            file_size = getattr(file_info, "size", 0) or 0
            modification_time = getattr(file_info, "mtime_ns", 0) or 0
            if modification_time > 0:
                modification_time = modification_time // 1_000_000
            access_time = 0
            owner = None

            paths.append(relative_path)
            names.append(file_name)
            lengths.append(file_size)
            mtimes.append(modification_time)
            atimes.append(access_time)
            owners.append(owner)

        if self.limit is not None and len(paths) >= self.limit:
            break

    result = pyarrow.table(
        {
            "path": pyarrow.array(paths, type=pyarrow.string()),
            "name": pyarrow.array(names, type=pyarrow.string()),
            "length": pyarrow.array(lengths, type=pyarrow.int64()),
            "mtime": pyarrow.array(mtimes, type=pyarrow.int64()),
            "atime": pyarrow.array(atimes, type=pyarrow.int64()),
            "owner": pyarrow.array(owners, type=pyarrow.string()),
        },
        schema=OBJECT_TABLE_ARROW_SCHEMA,
    )

    if self.projection:
        existing = [c for c in self.projection if c in result.column_names]
        if existing:
            result = result.select(existing)

    return result
