// Generated by Lisette bindgen
// Source: archive/tar (Go stdlib)
// Go: 1.25.10
// Lisette: 0.3.0

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

/// FileInfoHeader creates a partially-populated [Header] from fi.
/// If fi describes a symlink, FileInfoHeader records link as the link target.
/// If fi describes a directory, a slash is appended to the name.
/// 
/// Since fs.FileInfo's Name method only returns the base name of
/// the file it describes, it may be necessary to modify Header.Name
/// to provide the full path name of the file.
/// 
/// If fi implements [FileInfoNames]
/// Header.Gname and Header.Uname
/// are provided by the methods of the interface.
pub fn FileInfoHeader(fi: fs.FileInfo, link: string) -> Result<Ref<Header>, error>

/// NewReader creates a new [Reader] reading from r.
pub fn NewReader(r: io.Reader) -> Ref<Reader>

/// NewWriter creates a new Writer writing to w.
pub fn NewWriter(w: io.Writer) -> Ref<Writer>

/// FileInfoNames extends [fs.FileInfo].
/// Passing an instance of this to [FileInfoHeader] permits the caller
/// to avoid a system-dependent name lookup by specifying the Uname and Gname directly.
pub interface FileInfoNames {
  fn Gname() -> Result<string, error>
  fn IsDir() -> bool
  fn ModTime() -> time.Time
  fn Mode() -> fs.FileMode
  fn Name() -> string
  fn Size() -> int64
  fn Sys() -> Unknown
  fn Uname() -> Result<string, error>
}

/// Format represents the tar archive format.
/// 
/// The original tar format was introduced in Unix V7.
/// Since then, there have been multiple competing formats attempting to
/// standardize or extend the V7 format to overcome its limitations.
/// The most common formats are the USTAR, PAX, and GNU formats,
/// each with their own advantages and limitations.
/// 
/// The following table captures the capabilities of each format:
/// 
/// 	                  |  USTAR |       PAX |       GNU
/// 	------------------+--------+-----------+----------
/// 	Name              |   256B | unlimited | unlimited
/// 	Linkname          |   100B | unlimited | unlimited
/// 	Size              | uint33 | unlimited |    uint89
/// 	Mode              | uint21 |    uint21 |    uint57
/// 	Uid/Gid           | uint21 | unlimited |    uint57
/// 	Uname/Gname       |    32B | unlimited |       32B
/// 	ModTime           | uint33 | unlimited |     int89
/// 	AccessTime        |    n/a | unlimited |     int89
/// 	ChangeTime        |    n/a | unlimited |     int89
/// 	Devmajor/Devminor | uint21 |    uint21 |    uint57
/// 	------------------+--------+-----------+----------
/// 	string encoding   |  ASCII |     UTF-8 |    binary
/// 	sub-second times  |     no |       yes |        no
/// 	sparse files      |     no |       yes |       yes
/// 
/// The table's upper portion shows the [Header] fields, where each format reports
/// the maximum number of bytes allowed for each string field and
/// the integer type used to store each numeric field
/// (where timestamps are stored as the number of seconds since the Unix epoch).
/// 
/// The table's lower portion shows specialized features of each format,
/// such as supported string encodings, support for sub-second timestamps,
/// or support for sparse files.
/// 
/// The Writer currently provides no support for sparse files.
#[go(bit_flag_set)]
pub struct Format(int)

/// A Header represents a single header in a tar archive.
/// Some fields may not be populated.
/// 
/// For forward compatibility, users that retrieve a Header from Reader.Next,
/// mutate it in some ways, and then pass it back to Writer.WriteHeader
/// should do so by creating a new Header and copying the fields
/// that they are interested in preserving.
pub struct Header {
  pub Typeflag: byte,
  pub Name: string,
  pub Linkname: string,
  pub Size: int64,
  pub Mode: int64,
  pub Uid: int,
  pub Gid: int,
  pub Uname: string,
  pub Gname: string,
  pub ModTime: time.Time,
  pub AccessTime: time.Time,
  pub ChangeTime: time.Time,
  pub Devmajor: int64,
  pub Devminor: int64,
  pub Xattrs: Map<string, string>,
  pub PAXRecords: Map<string, string>,
  pub Format: Format,
}

/// Reader provides sequential access to the contents of a tar archive.
/// Reader.Next advances to the next file in the archive (including the first),
/// and then Reader can be treated as an io.Reader to access the file's data.
pub type Reader

/// Writer provides sequential writing of a tar archive.
/// [Writer.WriteHeader] begins a new file with the provided [Header],
/// and then Writer can be treated as an io.Writer to supply that file's data.
pub type Writer

pub const FormatGNU: Format = 8

pub const FormatPAX: Format = 4

pub const FormatUSTAR: Format = 2

pub const FormatUnknown: Format = 0

/// Type flags for Header.Typeflag.
pub const TypeBlock = 52

/// Type flags for Header.Typeflag.
pub const TypeChar = 51

/// Type flags for Header.Typeflag.
pub const TypeCont = 55

/// Type flags for Header.Typeflag.
pub const TypeDir = 53

/// Type flags for Header.Typeflag.
pub const TypeFifo = 54

/// Type flags for Header.Typeflag.
pub const TypeGNULongLink = 75

/// Type flags for Header.Typeflag.
pub const TypeGNULongName = 76

/// Type flags for Header.Typeflag.
pub const TypeGNUSparse = 83

/// Type flags for Header.Typeflag.
pub const TypeLink = 49

/// Type flags for Header.Typeflag.
pub const TypeReg = 48

/// Type flags for Header.Typeflag.
pub const TypeRegA = 0

/// Type flags for Header.Typeflag.
pub const TypeSymlink = 50

/// Type flags for Header.Typeflag.
pub const TypeXGlobalHeader = 103

/// Type flags for Header.Typeflag.
pub const TypeXHeader = 120

pub var ErrFieldTooLong: error

pub var ErrHeader: error

pub var ErrInsecurePath: error

pub var ErrWriteAfterClose: error

pub var ErrWriteTooLong: error

impl Format {
  fn String(self) -> string
}

impl Header {
  /// FileInfo returns an fs.FileInfo for the Header.
  fn FileInfo(self: Ref<Header>) -> fs.FileInfo
}

impl Reader {
  /// Next advances to the next entry in the tar archive.
  /// The Header.Size determines how many bytes can be read for the next file.
  /// Any remaining data in the current file is automatically discarded.
  /// At the end of the archive, Next returns the error io.EOF.
  /// 
  /// If Next encounters a non-local name (as defined by [filepath.IsLocal])
  /// and the GODEBUG environment variable contains `tarinsecurepath=0`,
  /// Next returns the header with an [ErrInsecurePath] error.
  /// A future version of Go may introduce this behavior by default.
  /// Programs that want to accept non-local names can ignore
  /// the [ErrInsecurePath] error and use the returned header.
  fn Next(self: Ref<Reader>) -> Result<Ref<Header>, error>

  /// Read reads from the current file in the tar archive.
  /// It returns (0, io.EOF) when it reaches the end of that file,
  /// until [Next] is called to advance to the next file.
  /// 
  /// If the current file is sparse, then the regions marked as a hole
  /// are read back as NUL-bytes.
  /// 
  /// Calling Read on special types like [TypeLink], [TypeSymlink], [TypeChar],
  /// [TypeBlock], [TypeDir], and [TypeFifo] returns (0, [io.EOF]) regardless of what
  /// the [Header.Size] claims.
  fn Read(self: Ref<Reader>, mut b: Slice<byte>) -> Partial<int, error>
}

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 tar archive while maintaining the directory structure.
  fn AddFS(self: Ref<Writer>, fsys: fs.FS) -> Result<(), error>

  /// Close closes the tar archive by flushing the padding, and writing the footer.
  /// If the current file (from a prior call to [Writer.WriteHeader]) is not fully written,
  /// then this returns an error.
  #[allow(unused_result)]
  fn Close(self: Ref<Writer>) -> Result<(), error>

  /// Flush finishes writing the current file's block padding.
  /// The current file must be fully written before Flush can be called.
  /// 
  /// This is unnecessary as the next call to [Writer.WriteHeader] or [Writer.Close]
  /// will implicitly flush out the file's padding.
  #[allow(unused_result)]
  fn Flush(self: Ref<Writer>) -> Result<(), error>

  /// Write writes to the current file in the tar archive.
  /// Write returns the error [ErrWriteTooLong] if more than
  /// Header.Size bytes are written after [Writer.WriteHeader].
  /// 
  /// Calling Write on special types like [TypeLink], [TypeSymlink], [TypeChar],
  /// [TypeBlock], [TypeDir], and [TypeFifo] returns (0, [ErrWriteTooLong]) regardless
  /// of what the [Header.Size] claims.
  fn Write(self: Ref<Writer>, b: Slice<byte>) -> Partial<int, error>

  /// WriteHeader writes hdr and prepares to accept the file's contents.
  /// The Header.Size determines how many bytes can be written for the next file.
  /// If the current file is not fully written, then this returns an error.
  /// This implicitly flushes any padding necessary before writing the header.
  fn WriteHeader(self: Ref<Writer>, hdr: Ref<Header>) -> Result<(), error>
}
