// Generated by Lisette bindgen
// Source: archive/zip (Go stdlib)
// Go: 1.25.5
// Lisette: 0.1.20

import "go:io"
import "go:io/fs"
import "go:time"

pub fn FileInfoHeader(fi: fs.FileInfo) -> Result<Ref<FileHeader>, error>

pub fn NewReader(r: io.ReaderAt, size: int64) -> Result<Ref<Reader>, error>

pub fn NewWriter(w: io.Writer) -> Ref<Writer>

pub fn OpenReader(name: string) -> Result<Ref<ReadCloser>, error>

/// RegisterCompressor registers custom compressors for a specified method ID.
/// The common methods [Store] and [Deflate] are built in.
pub fn RegisterCompressor(method: uint16, comp: Compressor)

/// RegisterDecompressor allows custom decompressors for a specified method ID.
/// The common methods [Store] and [Deflate] are built in.
pub fn RegisterDecompressor(method: uint16, dcomp: Decompressor)

/// A Compressor returns a new compressing writer, writing to w.
/// The WriteCloser's Close method must be used to flush pending data to w.
/// The Compressor itself must be safe to invoke from multiple goroutines
/// simultaneously, but each returned writer will be used only by
/// one goroutine at a time.
pub type Compressor = fn(io.Writer) -> Result<io.WriteCloser, error>

/// A Decompressor returns a new decompressing reader, reading from r.
/// The [io.ReadCloser]'s Close method must be used to release associated resources.
/// The Decompressor itself must be safe to invoke from multiple goroutines
/// simultaneously, but each returned reader will be used only by
/// one goroutine at a time.
pub type Decompressor = fn(io.Reader) -> io.ReadCloser

/// A File is a single file in a ZIP archive.
/// The file information is in the embedded [FileHeader].
/// The file content can be accessed by calling [File.Open].
pub struct File {
  pub FileHeader: FileHeader,
}

/// FileHeader describes a file within a ZIP file.
/// See the [ZIP specification] for details.
/// 
/// [ZIP specification]: https://support.pkware.com/pkzip/appnote
pub struct FileHeader {
  pub Name: string,
  pub Comment: string,
  pub NonUTF8: bool,
  pub CreatorVersion: uint16,
  pub ReaderVersion: uint16,
  pub Flags: uint16,
  pub Method: uint16,
  pub Modified: time.Time,
  pub ModifiedTime: uint16,
  pub ModifiedDate: uint16,
  pub CRC32: uint32,
  pub CompressedSize: uint32,
  pub UncompressedSize: uint32,
  pub CompressedSize64: uint64,
  pub UncompressedSize64: uint64,
  pub Extra: Slice<uint8>,
  pub ExternalAttrs: uint32,
}

/// A ReadCloser is a [Reader] that must be closed when no longer needed.
pub struct ReadCloser {
  pub Reader: Reader,
}

/// A Reader serves content from a ZIP archive.
pub struct Reader {
  pub File: Slice<Option<Ref<File>>>,
  pub Comment: string,
}

/// Writer implements a zip file writer.
pub type Writer

/// Compression methods.
const Deflate = 8

/// Compression methods.
const Store = 0

pub var ErrAlgorithm: error

pub var ErrChecksum: error

pub var ErrFormat: error

pub var ErrInsecurePath: error

impl File {
  /// DataOffset returns the offset of the file's possibly-compressed
  /// data, relative to the beginning of the zip file.
  /// 
  /// Most callers should instead use [File.Open], which transparently
  /// decompresses data and verifies checksums.
  fn DataOffset(self: Ref<File>) -> Result<int64, error>

  /// FileInfo returns an fs.FileInfo for the [FileHeader].
  fn FileInfo(self: Ref<File>) -> fs.FileInfo

  /// ModTime returns the modification time in UTC using the legacy
  /// [ModifiedDate] and [ModifiedTime] fields.
  /// 
  /// Deprecated: Use [Modified] instead.
  fn ModTime(self: Ref<File>) -> time.Time

  /// Mode returns the permission and mode bits for the [FileHeader].
  fn Mode(self: Ref<File>) -> fs.FileMode

  /// Open returns a [ReadCloser] that provides access to the [File]'s contents.
  /// Multiple files may be read concurrently.
  fn Open(self: Ref<File>) -> Result<io.ReadCloser, error>

  /// OpenRaw returns a [Reader] that provides access to the [File]'s contents without
  /// decompression.
  fn OpenRaw(self: Ref<File>) -> Result<io.Reader, error>

  /// SetModTime sets the [Modified], [ModifiedTime], and [ModifiedDate] fields
  /// to the given time in UTC.
  /// 
  /// Deprecated: Use [Modified] instead.
  fn SetModTime(self: Ref<File>, t: time.Time)

  /// SetMode changes the permission and mode bits for the [FileHeader].
  fn SetMode(self: Ref<File>, mode: fs.FileMode)
}

impl FileHeader {
  /// FileInfo returns an fs.FileInfo for the [FileHeader].
  fn FileInfo(self: Ref<FileHeader>) -> fs.FileInfo

  /// ModTime returns the modification time in UTC using the legacy
  /// [ModifiedDate] and [ModifiedTime] fields.
  /// 
  /// Deprecated: Use [Modified] instead.
  fn ModTime(self: Ref<FileHeader>) -> time.Time

  /// Mode returns the permission and mode bits for the [FileHeader].
  fn Mode(self: Ref<FileHeader>) -> fs.FileMode

  /// SetModTime sets the [Modified], [ModifiedTime], and [ModifiedDate] fields
  /// to the given time in UTC.
  /// 
  /// Deprecated: Use [Modified] instead.
  fn SetModTime(self: Ref<FileHeader>, t: time.Time)

  /// SetMode changes the permission and mode bits for the [FileHeader].
  fn SetMode(self: Ref<FileHeader>, mode: fs.FileMode)
}

impl ReadCloser {
  /// Close closes the Zip file, rendering it unusable for I/O.
  #[allow(unused_result)]
  fn Close(self: Ref<ReadCloser>) -> Result<(), error>

  /// Open opens the named file in the ZIP archive,
  /// using the semantics of fs.FS.Open:
  /// paths are always slash separated, with no
  /// leading / or ../ elements.
  fn Open(self: Ref<ReadCloser>, name: string) -> Result<fs.File, error>

  /// RegisterDecompressor registers or overrides a custom decompressor for a
  /// specific method ID. If a decompressor for a given method is not found,
  /// [Reader] will default to looking up the decompressor at the package level.
  fn RegisterDecompressor(
    self: Ref<ReadCloser>,
    method: uint16,
    dcomp: Decompressor,
  )
}

impl Reader {
  /// Open opens the named file in the ZIP archive,
  /// using the semantics of fs.FS.Open:
  /// paths are always slash separated, with no
  /// leading / or ../ elements.
  fn Open(self: Ref<Reader>, name: string) -> Result<fs.File, error>

  /// RegisterDecompressor registers or overrides a custom decompressor for a
  /// specific method ID. If a decompressor for a given method is not found,
  /// [Reader] will default to looking up the decompressor at the package level.
  fn RegisterDecompressor(
    self: Ref<Reader>,
    method: uint16,
    dcomp: Decompressor,
  )
}

impl Writer {
  /// AddFS adds the files from fs.FS to the archive.
  /// It walks the directory tree starting at the root of the filesystem
  /// adding each file to the zip using deflate while maintaining the directory structure.
  fn AddFS(self: Ref<Writer>, fsys: fs.FS) -> Result<(), error>

  /// Close finishes writing the zip file by writing the central directory.
  /// It does not close the underlying writer.
  #[allow(unused_result)]
  fn Close(self: Ref<Writer>) -> Result<(), error>

  /// Copy copies the file f (obtained from a [Reader]) into w. It copies the raw
  /// form directly bypassing decompression, compression, and validation.
  fn Copy(self: Ref<Writer>, f: Ref<File>) -> Result<(), error>

  /// Create adds a file to the zip file using the provided name.
  /// It returns a [Writer] to which the file contents should be written.
  /// The file contents will be compressed using the [Deflate] method.
  /// The name must be a relative path: it must not start with a drive
  /// letter (e.g. C:) or leading slash, and only forward slashes are
  /// allowed. To create a directory instead of a file, add a trailing
  /// slash to the name. Duplicate names will not overwrite previous entries
  /// and are appended to the zip file.
  /// The file's contents must be written to the [io.Writer] before the next
  /// call to [Writer.Create], [Writer.CreateHeader], or [Writer.Close].
  fn Create(self: Ref<Writer>, name: string) -> Result<io.Writer, error>

  /// CreateHeader adds a file to the zip archive using the provided [FileHeader]
  /// for the file metadata. [Writer] takes ownership of fh and may mutate
  /// its fields. The caller must not modify fh after calling [Writer.CreateHeader].
  /// 
  /// This returns a [Writer] to which the file contents should be written.
  /// The file's contents must be written to the io.Writer before the next
  /// call to [Writer.Create], [Writer.CreateHeader], [Writer.CreateRaw], or [Writer.Close].
  fn CreateHeader(self: Ref<Writer>, fh: Ref<FileHeader>) -> Result<io.Writer, error>

  /// CreateRaw adds a file to the zip archive using the provided [FileHeader] and
  /// returns a [Writer] to which the file contents should be written. The file's
  /// contents must be written to the io.Writer before the next call to [Writer.Create],
  /// [Writer.CreateHeader], [Writer.CreateRaw], or [Writer.Close].
  /// 
  /// In contrast to [Writer.CreateHeader], the bytes passed to Writer are not compressed.
  /// 
  /// CreateRaw's argument is stored in w. If the argument is a pointer to the embedded
  /// [FileHeader] in a [File] obtained from a [Reader] created from in-memory data,
  /// then w will refer to all of that memory.
  fn CreateRaw(self: Ref<Writer>, fh: Ref<FileHeader>) -> Result<io.Writer, error>

  /// Flush flushes any buffered data to the underlying writer.
  /// Calling Flush is not normally necessary; calling Close is sufficient.
  #[allow(unused_result)]
  fn Flush(self: Ref<Writer>) -> Result<(), error>

  /// RegisterCompressor registers or overrides a custom compressor for a specific
  /// method ID. If a compressor for a given method is not found, [Writer] will
  /// default to looking up the compressor at the package level.
  fn RegisterCompressor(self: Ref<Writer>, method: uint16, comp: Compressor)

  /// SetComment sets the end-of-central-directory comment field.
  /// It can only be called before [Writer.Close].
  fn SetComment(self: Ref<Writer>, comment: string) -> Result<(), error>

  /// SetOffset sets the offset of the beginning of the zip data within the
  /// underlying writer. It should be used when the zip data is appended to an
  /// existing file, such as a binary executable.
  /// It must be called before any data is written.
  fn SetOffset(self: Ref<Writer>, n: int64)
}
