---@meta archive

--------------------------------------------------------------------------------
-- libarchive C binding module
--------------------------------------------------------------------------------

---@alias archive_read_format 'all'|'ar'|'cpio'|'empty'|'gnutar'|'iso9660'|'mtree'|'tar'|'zip'|string
---@alias archive_read_compression 'all'|'bzip2'|'compress'|'gzip'|'lzma'|'none'|'xz'|string
---@alias archive_write_format 'ar'|'arbsd'|'argnu'|'arsvr4'|'cpio'|'mtree'|'newc'|'odc'|'pax'|'posix'|'shar'|'shardump'|'ustar'|'ar_bsd'|'ar_svr4'|'cpio_newc'|'pax_restricted'|'shar_dump'|string
---@alias archive_write_compression 'bzip2'|'compress'|'gzip'|'lzma'|'xz'|string
---@alias archive_reader_callback fun(ar:archive_reader*):string?
---@alias archive_writer_callback fun(ar:archive_writer*, data:string?):integer?
---@alias archive_time integer[]|{[1]:integer,[2]:integer}

---@class archive_read_options*
---@field reader archive_reader_callback Read callback; return nil to indicate end
---@field format? archive_read_format Supported format list text, default all
---@field compression? archive_read_compression Supported compressed list text, default none
---@field options? string libarchive option string

---@class archive_write_skip_file*
---@field dev integer Device number
---@field ino integer inode

---@class archive_write_options*
---@field writer archive_writer_callback Write callback; called with nil on close
---@field format? archive_write_format Writing format, default posix
---@field compression? archive_write_compression Compression format
---@field options? string libarchive option string
---@field bytes_per_block? integer Bytes per block
---@field bytes_in_last_block? integer Number of bytes in the last block
---@field skip_file? archive_write_skip_file* skip specified files

---@class archive_entry_options*
---@field fflags? string file flags
---@field dev? integer Device number
---@field ino? integer inode
---@field mode? integer file mode
---@field nlink? integer Number of hard links
---@field uid? integer user id
---@field uname? string user name
---@field gid? integer group id
---@field gname? string group name
---@field rdev? integer special device id
---@field atime? archive_time access time
---@field mtime? archive_time modification time
---@field ctime? archive_time change time
---@field birthtime? archive_time birth time
---@field size? integer file size
---@field sourcepath? string Source file path; stat information will be copied
---@field symlink? string symlink target
---@field hardlink? string hardlink target
---@field pathname? string archive inner path

---@class archive_entry*
local archive_entry = {}

---@param value? string
---@return string? value
function archive_entry:fflags(value) end

---@param value? integer
---@return integer value
function archive_entry:dev(value) end

---@param value? integer
---@return integer value
function archive_entry:ino(value) end

---@param value? integer
---@return integer value
function archive_entry:mode(value) end

---@param value? integer
---@return integer value
function archive_entry:nlink(value) end

---@param value? integer
---@return integer value
function archive_entry:uid(value) end

---@param value? string
---@return string? value
function archive_entry:uname(value) end

---@param value? integer
---@return integer value
function archive_entry:gid(value) end

---@param value? string
---@return string? value
function archive_entry:gname(value) end

---@param value? integer
---@return integer value
function archive_entry:rdev(value) end

---@param seconds? integer|archive_time|nil
---@param nsec? integer
---@return integer? seconds
---@return integer? nsec
function archive_entry:atime(seconds, nsec) end

---@param seconds? integer|archive_time|nil
---@param nsec? integer
---@return integer? seconds
---@return integer? nsec
function archive_entry:mtime(seconds, nsec) end

---@param seconds? integer|archive_time|nil
---@param nsec? integer
---@return integer? seconds
---@return integer? nsec
function archive_entry:ctime(seconds, nsec) end

---@param seconds? integer|archive_time|nil
---@param nsec? integer
---@return integer? seconds
---@return integer? nsec
function archive_entry:birthtime(seconds, nsec) end

---@param value? integer|nil
---@return integer? value
function archive_entry:size(value) end

---@param value? string
---@return string? value
function archive_entry:sourcepath(value) end

---@param value? string
---@return string? value
function archive_entry:symlink(value) end

---@param value? string
---@return string? value
function archive_entry:hardlink(value) end

---@param value? string
---@return string? value
function archive_entry:pathname(value) end

---@class archive_reader*
local archive_reader = {}

--- Read the next header.
---@return archive_entry*? entry entry; ends in nil
function archive_reader:next_header() end

--- Returns the header iterator.
---@return fun(ar:archive_reader*):archive_entry*? iter iterative function
---@return archive_reader* ar reader object
---@return nil initial initial value
function archive_reader:headers() end

--- Read the next piece of data of the current entry.
---@return string? data block of data; ends in nil
---@return integer? offset data offset
function archive_reader:data() end

--- Close reader.
function archive_reader:close() end

---@class archive_writer*
local archive_writer = {}

--- Write entry header.
---@param entry archive_entry* entry
function archive_writer:header(entry) end

--- Write entry data.
---@param data string data
function archive_writer:data(data) end

--- Close writer.
function archive_writer:close() end

---@class archive*
---@type archive*
local M = {}

--- Returns the underlying libarchive version number component.
---@return integer major major version
---@return integer minor minor version
---@return integer patch Revision number
---@return integer? build Build number
function M.version() end

--- Create archive reader.
---@param opts archive_read_options* Read options
---@return archive_reader* reader reader object
function M.read(opts) end

--- Create archive writer.
---@param opts archive_write_options* Write options
---@return archive_writer* writer writer object
function M.write(opts) end

--- Create archive entry.
---@param opts? archive_entry_options* entry initial field
---@return archive_entry* entry entry object
function M.entry(opts) end

--- Reader reference counting for debugging.
---@return integer count Reference counting
function M._read_ref_count() end

--- Writer reference counting for debugging.
---@return integer count Reference counting
function M._write_ref_count() end

--- Debug entry reference counting.
---@return integer count Reference counting
function M._entry_ref_count() end

return M
