/// Holds the possible TAR formats that a file could take.
///
/// This library supports the V7, USTAR, PAX, GNU, and STAR formats. The
/// [MaybeTarFormat] class generally describes any combination of those formats
/// and represents that we don't know the exact format yet. As soon as we do
/// know, the [TarFormat] enum represents the exact format of a header.
sealed class MaybeTarFormat {
  /// The TAR formats are encoded in powers of two in [_value], such that we
  /// can refine our guess via bit operations as we discover more information
  /// about the TAR file.
  /// A value of 0 means that the format is invalid.
  int get _value;

  factory MaybeTarFormat._(int value) {
    return switch (value) {
      1 => TarFormat.v7,
      2 => TarFormat.ustar,
      4 => TarFormat.pax,
      8 => TarFormat.gnu,
      16 => TarFormat.star,
      final other => _MaybeTarFormat(other),
    };
  }

  /// Returns a new [MaybeTarFormat] that signifies that it can be either
  /// `this` or [other]'s format.
  ///
  /// **Example:**
  /// ```dart
  /// TarFormat format = TarFormat.ustar | TarFormat.pax;
  /// ```
  ///
  /// The above code would signify that we have limited `format` to either
  /// the USTAR or PAX format, but need further information to refine the guess.
  MaybeTarFormat operator |(TarFormat other);

  /// Returns if [other] is a possible resolution of `this`.
  ///
  /// For example, a [TarFormat] with a value of 6 means that we do not have
  /// enough information to determine if it is [TarFormat.ustar] or
  /// [TarFormat.pax], so either of them could be possible resolutions of
  /// `this`.
  bool has(MaybeTarFormat other);

  /// Returns a new [TarFormat] that signifies that it can only be [other]'s
  /// format.
  ///
  /// **Example:**
  /// ```dart
  /// TarFormat format = TarFormat.PAX | TarFormat.USTAR;
  /// ...
  /// format = format.mayOnlyBe(TarFormat.USTAR);
  /// ```
  ///
  /// In the above example, we found that `format` could either be PAX or USTAR,
  /// but later learnt that it can only be the USTAR format.
  ///
  /// If `has(other) == false`, [mayOnlyBe] will result in an unknown
  /// [TarFormat].
  MaybeTarFormat mayOnlyBe(MaybeTarFormat other);

  /// Returns if this format might be valid.
  ///
  /// This returns true as well even if we have yet to fully determine what the
  /// format is.
  bool get valid;
}

/// A fully resolved tar format.
///
/// When we know that a tar entry must use a specific format, this is represented
/// with a value from this [TarFormat] enum.
enum TarFormat implements MaybeTarFormat {
  /// Original Unix Version 7 (V7) AT&T tar tool prior to standardization.
  ///
  /// The structure of the V7 Header consists of the following:
  ///
  /// Start | End | Field
  /// =========================================================================
  /// 0     | 100 | Path name, stored as null-terminated string.
  /// 100   | 108 | File mode, stored as an octal number in ASCII.
  /// 108   | 116 | User id of owner, as octal number in ASCII.
  /// 116   | 124 | Group id of owner, as octal number in ASCII.
  /// 124   | 136 | Size of file, as octal number in ASCII.
  /// 136   | 148 | Modification time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 148   | 156 | Header checksum, stored as an octal number in ASCII.
  /// 156   | 157 | Link flag, determines the kind of header.
  /// 157   | 257 | Link name, stored as a string.
  /// 257   | 512 | NUL pad.
  ///
  /// Unused bytes are set to NUL ('\x00')s
  ///
  /// Reference:
  /// https://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5&format=html
  /// https://www.gnu.org/software/tar/manual/html_chapter/tar_15.html#SEC188
  /// http://cdrtools.sourceforge.net/private/man/star/star.4.html
  v7(1, 'V7'),

  /// USTAR (Unix Standard TAR) header format defined in POSIX.1-1988.
  ///
  /// The structure of the USTAR Header consists of the following:
  ///
  /// Start | End | Field
  /// =========================================================================
  /// 0     | 100 | Path name, stored as null-terminated string.
  /// 100   | 108 | File mode, stored as an octal number in ASCII.
  /// 108   | 116 | User id of owner, as octal number in ASCII.
  /// 116   | 124 | Group id of owner, as octal number in ASCII.
  /// 124   | 136 | Size of file, as octal number in ASCII.
  /// 136   | 148 | Modification time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 148   | 156 | Header checksum, stored as an octal number in ASCII.
  /// 156   | 157 | Type flag, determines the kind of header.
  ///               Note that the meaning of the size field depends on the type.
  /// 157   | 257 | Link name, stored as a string.
  /// 257   | 263 | Contains the magic value "ustar\x00" to indicate that this is
  ///               the USTAR format. Full compliance requires user name and
  ///               group name fields to be set.
  /// 263   | 265 | Version. "00" for POSIX standard archives.
  /// 265   | 297 | User name, as null-terminated ASCII string.
  /// 297   | 329 | Group name, as null-terminated ASCII string.
  /// 329   | 337 | Major number for character or block device entry.
  /// 337   | 345 | Minor number for character or block device entry.
  /// 345   | 500 | Prefix. If the pathname is too long to fit in the 100 bytes
  ///               provided at the start, it can be split at any / character
  ///               with the first portion going here.
  /// 500   | 512 | NUL pad.
  ///
  /// Unused bytes are set to NUL ('\x00')s
  ///
  /// User and group names should be used in preference to uid/gid values when
  /// they are set and the corresponding names exist on the system.
  ///
  /// While this format is compatible with most tar readers, the format has
  /// several limitations making it unsuitable for some usages. Most notably, it
  /// cannot support sparse files, files larger than 8GiB, filenames larger than
  /// 256 characters, and non-ASCII filenames.
  ///
  /// Reference:
  /// https://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5&format=html
  /// https://www.gnu.org/software/tar/manual/html_chapter/tar_15.html#SEC188
  ///	http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06
  ustar(2, 'USTAR'),

  /// PAX header format defined in POSIX.1-2001.
  ///
  /// PAX extends USTAR by writing a special file with either the `x` or `g`
  /// type flags to allow for attributes that are not conveniently stored in a
  /// POSIX ustar archive to be held.
  ///
  /// Some newer formats add their own extensions to PAX by defining their
  /// own keys and assigning certain semantic meaning to the associated values.
  /// For example, sparse file support in PAX is implemented using keys
  /// defined by the GNU manual (e.g., "GNU.sparse.map").
  ///
  /// Reference:
  /// https://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5&format=html
  /// https://www.gnu.org/software/tar/manual/html_chapter/tar_15.html#SEC188
  /// http://cdrtools.sourceforge.net/private/man/star/star.4.html
  ///	http://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html
  pax(4, 'PAX'),

  /// GNU header format.
  ///
  /// The GNU header format is older than the USTAR and PAX standards and
  /// is not compatible with them. The GNU format supports
  /// arbitrary file sizes, filenames of arbitrary encoding and length,
  /// sparse files, and other features.
  ///
  /// Start | End | Field
  /// =========================================================================
  /// 0     | 100 | Path name, stored as null-terminated string.
  /// 100   | 108 | File mode, stored as an octal number in ASCII.
  /// 108   | 116 | User id of owner, as octal number in ASCII.
  /// 116   | 124 | Group id of owner, as octal number in ASCII.
  /// 124   | 136 | Size of file, as octal number in ASCII.
  /// 136   | 148 | Modification time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 148   | 156 | Header checksum, stored as an octal number in ASCII.
  /// 156   | 157 | Type flag, determines the kind of header.
  ///               Note that the meaning of the size field depends on the type.
  /// 157   | 257 | Link name, stored as a string.
  /// 257   | 263 | Contains the magic value "ustar " to indicate that this is
  ///               the GNU format.
  /// 263   | 265 | Version. " \x00" for POSIX standard archives.
  /// 265   | 297 | User name, as null-terminated ASCII string.
  /// 297   | 329 | Group name, as null-terminated ASCII string.
  /// 329   | 337 | Major number for character or block device entry.
  /// 337   | 345 | Minor number for character or block device entry.
  /// 345   | 357 | Last Access time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 357   | 369 | Last Changed time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 369   | 381 | Offset - not used.
  /// 381   | 385 | Longnames - deprecated
  /// 385   | 386 | Unused.
  /// 386   | 482 | Sparse data - 4 sets of (offset, numbytes) stored as
  ///               octal numbers in ASCII.
  /// 482   | 483 | isExtended - if this field is non-zero, this header is
  ///               followed by  additional sparse records, which are in the
  ///               same format as above.
  /// 483   | 495 | Binary representation of the file's complete size, inclusive
  ///               of the sparse data.
  /// 495   | 512 | NUL pad.
  ///
  /// It is recommended that PAX be chosen over GNU unless the target
  /// application can only parse GNU formatted archives.
  ///
  /// Reference:
  ///	https://www.gnu.org/software/tar/manual/html_node/Standard.html
  gnu(8, 'GNU'),

  /// Schily's TAR format, which is incompatible with USTAR.
  /// This does not cover STAR extensions to the PAX format; these fall under
  /// the PAX format.
  ///
  /// Start | End | Field
  /// =========================================================================
  /// 0     | 100 | Path name, stored as null-terminated string.
  /// 100   | 108 | File mode, stored as an octal number in ASCII.
  /// 108   | 116 | User id of owner, as octal number in ASCII.
  /// 116   | 124 | Group id of owner, as octal number in ASCII.
  /// 124   | 136 | Size of file, as octal number in ASCII.
  /// 136   | 148 | Modification time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 148   | 156 | Header checksum, stored as an octal number in ASCII.
  /// 156   | 157 | Type flag, determines the kind of header.
  ///               Note that the meaning of the size field depends on the type.
  /// 157   | 257 | Link name, stored as a string.
  /// 257   | 263 | Contains the magic value "ustar\x00" to indicate that this is
  ///               the GNU format.
  /// 263   | 265 | Version. "00" for STAR archives.
  /// 265   | 297 | User name, as null-terminated ASCII string.
  /// 297   | 329 | Group name, as null-terminated ASCII string.
  /// 329   | 337 | Major number for character or block device entry.
  /// 337   | 345 | Minor number for character or block device entry.
  /// 345   | 476 | Prefix. If the pathname is too long to fit in the 100 bytes
  ///               provided at the start, it can be split at any / character
  ///               with the first portion going here.
  /// 476   | 488 | Last Access time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 488   | 500 | Last Changed time of file, number of seconds from epoch,
  ///               stored as an octal number in ASCII.
  /// 500   | 508 | NUL pad.
  /// 508   | 512 | Trailer - "tar\x00".
  ///
  /// Reference:
  /// http://cdrtools.sourceforge.net/private/man/star/star.4.html
  star(16, 'STAR'),
  ;

  @override
  final int _value;

  final String _name;

  const TarFormat(this._value, this._name);

  @override
  bool get valid => true;

  @override
  MaybeTarFormat operator |(TarFormat other) {
    return other == this ? this : _MaybeTarFormat(_value | other._value);
  }

  @override
  bool has(MaybeTarFormat other) {
    return other == this;
  }

  @override
  MaybeTarFormat mayOnlyBe(MaybeTarFormat other) {
    return MaybeTarFormat._(_value & other._value);
  }

  @override
  String toString() => _name;
}

final class _MaybeTarFormat implements MaybeTarFormat {
  // Note: We never represent a single tar format in a _MaybeTarFormat, these
  // are represented in the TarFormat enum.
  @override
  final int _value;

  const _MaybeTarFormat(this._value);

  @override
  int get hashCode => _value;

  @override
  bool operator ==(Object other) {
    if (other is! TarFormat) return false;

    return _value == other._value;
  }

  @override
  String toString() {
    if (!valid) return 'Invalid';

    return TarFormat.values.where(has).map((e) => e._name).join(' or ');
  }

  @override
  bool has(MaybeTarFormat other) => _value & other._value != 0;

  @override
  bool get valid => _value != 0;

  @override
  MaybeTarFormat mayOnlyBe(MaybeTarFormat other) {
    return MaybeTarFormat._(_value & other._value);
  }

  @override
  MaybeTarFormat operator |(TarFormat other) {
    return MaybeTarFormat._(_value | other._value);
  }
}
