"""Frozen 0.25.3 source read implementation used only by the cost experiment."""
from __future__ import annotations
import os
import stat
from hashlib import sha256
from collections.abc import Iterator
from h2hdb_ingest.filesystem import (
    FilesystemFileObservation, FilesystemObservationError,
    FilesystemSourceChangedError, _READ_BYTES, _source_io_error,
)

class HistoricalFileObservation(FilesystemFileObservation):
    def content_parts(self) -> Iterator[bytes]:
        """Yield exact file bytes after a no-follow open and stat check."""

        self._checkpoint()
        if self._snapshot is not None:
            # Completion markers already own an exact bounded no-follow read.
            # The core still derives its content receipt from these bytes.
            yield self._snapshot
            self._checkpoint()
            if self._progress is not None:
                self._progress.advance("file_observations_completed")
            return
        directory_descriptor: int | None = None
        descriptor: int | None = None
        try:
            directory_descriptor = os.open(
                self.folder,
                os.O_RDONLY | getattr(os, "O_DIRECTORY", 0),
            )
            descriptor = os.open(
                self.name_bytes,
                os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0),
                dir_fd=directory_descriptor,
            )
            opened = os.fstat(descriptor)
            if not stat.S_ISREG(opened.st_mode):
                raise FilesystemObservationError(
                    f"source entry is no longer regular: {self.path}"
                )
            self._require_stat(opened, stage="before read")
            digest = sha256()
            while True:
                self._checkpoint()
                with self._source_performance.phase("read"):
                    part = os.read(descriptor, _READ_BYTES)
                if not part:
                    break
                with self._source_performance.phase("hash"):
                    digest.update(part)
                self._source_performance.add("logical_bytes_read", len(part))
                if self._progress is not None:
                    self._progress.advance("source_bytes_read", len(part))
                yield part
            self._checkpoint()
            self._require_stat(os.fstat(descriptor), stage="after read")
            if self.expected_sha256 is not None and digest.digest() != (
                self.expected_sha256
            ):
                raise FilesystemSourceChangedError(
                    f"source metadata bytes changed after parsing: {self.path}"
                )
            if self._progress is not None:
                self._progress.advance("file_observations_completed")
        except OSError as error:
            raise _source_io_error(
                f"unable to read source file {self.path}: {error}", error
            ) from error
        finally:
            if descriptor is not None:
                os.close(descriptor)
            if directory_descriptor is not None:
                os.close(directory_descriptor)
