// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:collection';
import 'dart:convert';
import 'dart:io' as io;

import 'package:archive/archive.dart' as a;
import 'package:path/path.dart' as path;

import 'cache.dart';
import 'limits.dart';

enum FileType {
  binary, // won't have its own license block
  text, // might have its own UTF-8 license block
  latin1Text, // might have its own Windows-1252 license block
  zip, // should be parsed as an archive and drilled into
  tar, // should be parsed as an archive and drilled into
  gz, // should be parsed as a single compressed file and exposed
  bzip2, // should be parsed as a single compressed file and exposed
  metadata, // can be skipped entirely (e.g. Mac OS X ._foo files)
}

typedef Reader = List<int> Function();

class BytesOf extends Key { BytesOf(dynamic value) : super(value); }
class UTF8Of extends Key { UTF8Of(dynamic value) : super(value); }
class Latin1Of extends Key { Latin1Of(dynamic value) : super(value); }

bool matchesSignature(List<int> bytes, List<int> signature) {
  if (bytes.length < signature.length) {
    return false;
  }
  for (int index = 0; index < signature.length; index += 1) {
    if (signature[index] != -1 && bytes[index] != signature[index]) {
      return false;
    }
  }
  return true;
}

bool hasSubsequence(List<int> bytes, List<int> signature, int limit) {
  if (bytes.length < limit) {
    limit = bytes.length;
  }
  for (int index = 0; index < limit; index += 1) {
    if (bytes.length - index < signature.length) {
      return false;
    }
    for (int offset = 0; offset < signature.length; offset += 1) {
      if (signature[offset] != -1 && bytes[index + offset] != signature[offset]) {
        break;
      }
      if (offset + 1 == signature.length) {
        return true;
      }
    }
  }
  return false;
}

const String kMultiLicenseFileHeader = 'Notices for files contained in';

bool isMultiLicenseNotice(Reader reader) {
  final List<int> bytes = reader();
  return ascii.decode(bytes.take(kMultiLicenseFileHeader.length).toList(), allowInvalid: true) == kMultiLicenseFileHeader;
}

FileType identifyFile(String name, Reader reader) {
  List<int>? bytes;
  if ((path.split(name).reversed.take(6).toList().reversed.join('/') == 'third_party/icu/source/extra/uconv/README') || // This specific ICU README isn't in UTF-8.
      (path.split(name).reversed.take(6).toList().reversed.join('/') == 'third_party/icu/source/samples/uresb/sr.txt') || // This specific sample contains non-UTF-8 data (unlike other sr.txt files).
      (path.split(name).reversed.take(2).toList().reversed.join('/') == 'builds/detect.mk') || // This specific freetype sample contains non-UTF-8 data (unlike other .mk files).
      (path.split(name).reversed.take(3).toList().reversed.join('/') == 'third_party/cares/cares.rc')) {
    return FileType.latin1Text;
  }
  if (path.split(name).reversed.take(6).toList().reversed.join('/') == 'dart/runtime/tests/vm/dart/bad_snapshot' || // Not any particular format
      path.split(name).reversed.take(8).toList().reversed.join('/') == 'third_party/android_tools/ndk/sources/cxx-stl/stlport/src/stlport.rc') {
    return FileType.binary;
  }
  final String base = path.basename(name);
  if (base.startsWith('._')) {
    bytes ??= reader();
    if (matchesSignature(bytes, <int>[0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58])) {
      return FileType.metadata;
    } // The ._* files in Mac OS X archives that gives icons and stuff
  }
  if (path.split(name).contains('cairo')) {
    bytes ??= reader();
    // "Copyright <latin1 copyright symbol> "
    if (hasSubsequence(bytes, <int>[0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0xA9, 0x20], kMaxSize)) {
      return FileType.latin1Text;
    }
  }
  switch (base) {
    // Build files
    case 'DEPS': return FileType.text;
    case 'MANIFEST': return FileType.text;
    // Licenses
    case 'COPYING': return FileType.text;
    case 'LICENSE': return FileType.text;
    case 'NOTICE.txt': return isMultiLicenseNotice(reader) ? FileType.binary : FileType.text;
    case 'NOTICE': return FileType.text;
    // Documentation
    case 'Changes': return FileType.text;
    case 'change.log': return FileType.text;
    case 'ChangeLog': return FileType.text;
    case 'CHANGES.0': return FileType.latin1Text;
    case 'README': return FileType.text;
    case 'TODO': return FileType.text;
    case 'NEWS': return FileType.text;
    case 'README.chromium': return FileType.text;
    case 'README.flutter': return FileType.text;
    case 'README.tests': return FileType.text;
    case 'OWNERS': return FileType.text;
    case 'AUTHORS': return FileType.text;
    // Signatures (found in .jar files typically)
    case 'CERT.RSA': return FileType.binary;
    case 'ECLIPSE_.RSA': return FileType.binary;
    // Binary data files
    case 'tzdata': return FileType.binary;
    case 'compressed_atrace_data.txt': return FileType.binary;
    // Source files that don't use UTF-8
    case 'Messages_de_DE.properties': // has a few non-ASCII characters they forgot to escape (from gnu-libstdc++)
    case 'mmx_blendtmp.h': // author name in comment contains latin1 (mesa)
    case 'calling_convention.txt': // contains a soft hyphen instead of a real hyphen for some reason (mesa)
    // Character encoding data files
    case 'danish-ISO-8859-1.txt':
    case 'eucJP.txt':
    case 'hangul-eucKR.txt':
    case 'hania-eucKR.txt':
    case 'ibm-37-test.txt':
    case 'iso8859-1.txt':
    case 'ISO-8859-2.txt':
    case 'ISO-8859-3.txt':
    case 'koi8r.txt':
      return FileType.latin1Text;
    // Giant data files
    case 'icudtl_dat.S':
    case 'icudtl.dat':
    case 'icudtl.dat.hash':
      return FileType.binary;
  }
  switch (path.extension(name)) {
    // C/C++ code
    case '.h': return FileType.text;
    case '.c': return FileType.text;
    case '.cc': return FileType.text;
    case '.cpp': return FileType.text;
    case '.inc': return FileType.text;
    // ObjectiveC code
    case '.m': return FileType.text;
    // Assembler
    case '.asm': return FileType.text;
    // Shell
    case '.sh': return FileType.text;
    case '.bat': return FileType.text;
    // Build files
    case '.in': return FileType.text;
    case '.ac': return FileType.text;
    case '.am': return FileType.text;
    case '.gn': return FileType.text;
    case '.gni': return FileType.text;
    case '.gyp': return FileType.text;
    case '.gypi': return FileType.text;
    // Java code
    case '.java': return FileType.text;
    case '.jar': return FileType.zip; // Java package
    case '.class': return FileType.binary; // compiled Java bytecode (usually found inside .jar archives)
    case '.dex': return FileType.binary; // Dalvik Executable (usually found inside .jar archives)
    // Dart code
    case '.dart': return FileType.text;
    case '.dill': return FileType.binary; // Compiled Dart code
    // LLVM bitcode
    case '.bc': return FileType.binary;
    // Python code
    case '.py':
      bytes ??= reader();
      // # -*- coding: Latin-1 -*-
      if (matchesSignature(bytes, <int>[0x23, 0x20, 0x2d, 0x2a, 0x2d, 0x20, 0x63, 0x6f, 0x64,
                                        0x69, 0x6e, 0x67, 0x3a, 0x20, 0x4c, 0x61, 0x74, 0x69,
                                        0x6e, 0x2d, 0x31, 0x20, 0x2d, 0x2a, 0x2d])) {
        return FileType.latin1Text;
      }
      return FileType.text;
    case '.pyc': return FileType.binary; // compiled Python bytecode
    // Machine code
    case '.so': return FileType.binary; // ELF shared object
    case '.xpt': return FileType.binary; // XPCOM Type Library
    // Graphics code
    case '.glsl': return FileType.text;
    case '.spvasm': return FileType.text;
    // Documentation
    case '.md': return FileType.text;
    case '.txt': return FileType.text;
    case '.html': return FileType.text;
    // Fonts
    case '.ttf': return FileType.binary; // TrueType Font
    case '.ttcf': // (mac)
    case '.ttc': return FileType.binary; // TrueType Collection (windows)
    case '.woff': return FileType.binary; // Web Open Font Format
    case '.otf': return FileType.binary; // OpenType Font
    // Graphics formats
    case '.gif': return FileType.binary; // GIF
    case '.png': return FileType.binary; // PNG
    case '.tga': return FileType.binary; // Truevision TGA (TARGA)
    case '.dng': return FileType.binary; // Digial Negative (Adobe RAW format)
    case '.jpg':
    case '.jpeg': return FileType.binary; // JPEG
    case '.ico': return FileType.binary; // Windows icon format
    case '.icns': return FileType.binary; // macOS icon format
    case '.bmp': return FileType.binary; // Windows bitmap format
    case '.wbmp': return FileType.binary; // Wireless bitmap format
    case '.webp': return FileType.binary; // WEBP
    case '.pdf': return FileType.binary; // PDF
    case '.emf': return FileType.binary; // Windows enhanced metafile format
    case '.skp': return FileType.binary; // Skia picture format
    case '.mskp': return FileType.binary; // Skia picture format
    // Videos
    case '.ogg': return FileType.binary; // Ogg media
    case '.mp4': return FileType.binary; // MPEG media
    case '.ts': return FileType.binary; // MPEG2 transport stream
    // Other binary files
    case '.raw': return FileType.binary; // raw audio or graphical data
    case '.bin': return FileType.binary; // some sort of binary data
    case '.rsc': return FileType.binary; // some sort of resource data
    case '.arsc': return FileType.binary; // Android compiled resources
    case '.apk': return FileType.zip; // Android Package
    case '.crx': return FileType.binary; // Chrome extension
    case '.keystore': return FileType.binary;
    case '.icc': return FileType.binary; // Color profile
    case '.swp': return FileType.binary; // Vim swap file
    case '.bfbs': return FileType.binary; // Flatbuffers Binary Schema
    // Archives
    case '.zip': return FileType.zip; // ZIP
    case '.tar': return FileType.tar; // Tar
    case '.gz': return FileType.gz; // GZip
    case '.bzip2': return FileType.bzip2; // BZip2
    // Image file types from the Fuchsia SDK.
    case '.blk':
    case '.vboot':
    case '.snapshot':
    case '.zbi':
      return FileType.binary;
    // Special cases
    case '.patch':
    case '.diff':
      // Don't try to read the copyright out of patch files, since there'll be fragments.
      return FileType.binary;
    case '.plist':
      // These commonly include the word "copyright" but in a way that isn't necessarily a copyright statement that applies to the file.
      // Since there's so few of them, and none have their own copyright statement, we just treat them as binary files.
      return FileType.binary;
  }
  bytes ??= reader();
  assert(bytes.isNotEmpty);
  if (matchesSignature(bytes, <int>[0x1F, 0x8B])) {
    return FileType.gz;
  } // GZip archive
  if (matchesSignature(bytes, <int>[0x42, 0x5A])) {
    return FileType.bzip2;
  } // BZip2 archive
  if (matchesSignature(bytes, <int>[0x42, 0x43])) {
    return FileType.binary;
  } // LLVM Bitcode
  if (matchesSignature(bytes, <int>[0xAC, 0xED])) {
    return FileType.binary;
  } // Java serialized object
  if (matchesSignature(bytes, <int>[0x4D, 0x5A])) {
    return FileType.binary;
  } // MZ executable (DOS, Windows PEs, etc)
  if (matchesSignature(bytes, <int>[0xFF, 0xD8, 0xFF])) {
    return FileType.binary;
  } // JPEG
  if (matchesSignature(bytes, <int>[-1, -1, 0xda, 0x27])) {
    return FileType.binary;
  } // ICU data files (.brk, .dict, etc)
  if (matchesSignature(bytes, <int>[0x03, 0x00, 0x08, 0x00])) {
    return FileType.binary;
  } // Android Binary XML
  if (matchesSignature(bytes, <int>[0x25, 0x50, 0x44, 0x46])) {
    return FileType.binary;
  } // PDF
  if (matchesSignature(bytes, <int>[0x43, 0x72, 0x32, 0x34])) {
    return FileType.binary;
  } // Chrome extension
  if (matchesSignature(bytes, <int>[0x4F, 0x67, 0x67, 0x53])) {
    return FileType.binary;
  } // Ogg media
  if (matchesSignature(bytes, <int>[0x50, 0x4B, 0x03, 0x04])) {
    return FileType.zip;
  } // ZIP archive
  if (matchesSignature(bytes, <int>[0x7F, 0x45, 0x4C, 0x46])) {
    return FileType.binary;
  } // ELF
  if (matchesSignature(bytes, <int>[0xCA, 0xFE, 0xBA, 0xBE])) {
    return FileType.binary;
  } // compiled Java bytecode (usually found inside .jar archives)
  if (matchesSignature(bytes, <int>[0xCE, 0xFA, 0xED, 0xFE])) {
    return FileType.binary;
  } // Mach-O binary, 32 bit, reverse byte ordering scheme
  if (matchesSignature(bytes, <int>[0xCF, 0xFA, 0xED, 0xFE])) {
    return FileType.binary;
  } // Mach-O binary, 64 bit, reverse byte ordering scheme
  if (matchesSignature(bytes, <int>[0xFE, 0xED, 0xFA, 0xCE])) {
    return FileType.binary;
  } // Mach-O binary, 32 bit
  if (matchesSignature(bytes, <int>[0xFE, 0xED, 0xFA, 0xCF])) {
    return FileType.binary;
  } // Mach-O binary, 64 bit
  if (matchesSignature(bytes, <int>[0x75, 0x73, 0x74, 0x61, 0x72])) {
    return FileType.bzip2;
  } // Tar
  if (matchesSignature(bytes, <int>[0x47, 0x49, 0x46, 0x38, 0x37, 0x61])) {
    return FileType.binary;
  } // GIF87a
  if (matchesSignature(bytes, <int>[0x47, 0x49, 0x46, 0x38, 0x39, 0x61])) {
    return FileType.binary;
  } // GIF89a
  if (matchesSignature(bytes, <int>[0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00])) {
    return FileType.binary;
  } // Dalvik Executable
  if (matchesSignature(bytes, <int>[0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A])) {
    // TODO(ianh): implement .ar parser, https://github.com/flutter/flutter/issues/25633
    return FileType.binary; // Unix archiver (ar)
  }
  if (matchesSignature(bytes, <int>[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0a])) {
    return FileType.binary;
  } // PNG
  if (matchesSignature(bytes, <int>[0x58, 0x50, 0x43, 0x4f, 0x4d, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x4c, 0x69, 0x62, 0x0d, 0x0a, 0x1a])) {
    return FileType.binary;
  } // XPCOM Type Library
  return FileType.text;
}


// INTERFACE

// base class
abstract class IoNode {
  // Subclasses of IoNode are not mutually exclusive.
  // For example, a ZIP file is represented as a File that also implements Directory.
  String get name;
  String get fullName;

  @override
  String toString() => fullName;
}

// interface
abstract class File extends IoNode {
  List<int>? readBytes();
}

// interface
abstract class TextFile extends File {
  String readString();
}

mixin UTF8TextFile implements TextFile {
  @override
  String readString() {
    try {
      return cache(UTF8Of(this), () => utf8.decode(readBytes()!));
    } on FormatException {
      print(fullName);
      rethrow;
    }
  }
}

mixin Latin1TextFile implements TextFile {
  @override
  String readString() {
    return cache(Latin1Of(this), () {
      final List<int> bytes = readBytes()!;
      if (bytes.any((int byte) => byte == 0x00)) {
        throw '$fullName contains a U+0000 NULL and is probably not actually encoded as Win1252';
      }
      bool isUTF8 = false;
      try {
        cache(UTF8Of(this), () => utf8.decode(readBytes()!));
        isUTF8 = true;
      } on FormatException {
        // Exceptions are fine/expected for non-UTF8 text, which we test for
        // immediately below.
      }
      if (isUTF8) {
        throw '$fullName contains valid UTF-8 and is probably not actually encoded as Win1252';
      }
      return latin1.decode(bytes);
    });
  }
}

// interface
abstract class Directory extends IoNode {
  Iterable<IoNode> get walk;
}

// interface
abstract class Link extends IoNode { }

mixin ZipFile on File implements Directory {
  ArchiveDirectory? _root;

  @override
  Iterable<IoNode> get walk {
    try {
      _root ??= ArchiveDirectory.parseArchive(a.ZipDecoder().decodeBytes(readBytes()!), fullName);
      return _root!.walk;
    } catch (exception) {
      print('failed to parse archive:\n$fullName');
      rethrow;
    }
  }
}

mixin TarFile on File implements Directory {
  ArchiveDirectory? _root;

  @override
  Iterable<IoNode> get walk {
    try {
      _root ??= ArchiveDirectory.parseArchive(a.TarDecoder().decodeBytes(readBytes()!), fullName);
      return _root!.walk;
    } catch (exception) {
      print('failed to parse archive:\n$fullName');
      rethrow;
    }
  }
}

mixin GZipFile on File implements Directory {
  InMemoryFile? _data;

  @override
  Iterable<IoNode> get walk sync* {
    try {
      final String innerName = path.basenameWithoutExtension(fullName);
      _data ??= InMemoryFile.parse('$fullName!$innerName', a.GZipDecoder().decodeBytes(readBytes()!))!;
      if (_data != null) {
        yield _data!;
      }
    } catch (exception) {
      print('failed to parse archive:\n$fullName');
      rethrow;
    }
  }
}

mixin BZip2File on File implements Directory {
  InMemoryFile? _data;

  @override
  Iterable<IoNode> get walk sync* {
    try {
      final String innerName = path.basenameWithoutExtension(fullName);
      _data ??= InMemoryFile.parse('$fullName!$innerName', a.BZip2Decoder().decodeBytes(readBytes()!))!;
      if (_data != null) {
        yield _data!;
      }
    } catch (exception) {
      print('failed to parse archive:\n$fullName');
      rethrow;
    }
  }
}


// FILESYSTEM IMPLEMENTATIoN

class FileSystemDirectory extends IoNode implements Directory {
  FileSystemDirectory(this._directory);

  factory FileSystemDirectory.fromPath(String name) {
    return FileSystemDirectory(io.Directory(name));
  }

  final io.Directory _directory;

  @override
  String get name => path.basename(_directory.path);

  @override
  String get fullName => _directory.path;

  List<int> _readBytes(io.File file) {
    return cache/*List<int>*/(BytesOf(file), () => file.readAsBytesSync());
  }

  @override
  Iterable<IoNode> get walk sync* {
    final List<io.FileSystemEntity> list = _directory.listSync().toList();
    list.sort((io.FileSystemEntity a, io.FileSystemEntity b) => a.path.compareTo(b.path));
    for (final io.FileSystemEntity entity in list) {
      if (entity is io.Directory) {
        yield FileSystemDirectory(entity);
      } else if (entity is io.Link) {
        yield FileSystemLink(entity);
      } else {
        assert(entity is io.File);
        final io.File fileEntity = entity as io.File;
        if (fileEntity.lengthSync() > 0) {
          switch (identifyFile(fileEntity.path, () => _readBytes(fileEntity))) {
            case FileType.binary: yield FileSystemFile(fileEntity); break;
            case FileType.zip: yield FileSystemZipFile(fileEntity); break;
            case FileType.tar: yield FileSystemTarFile(fileEntity); break;
            case FileType.gz: yield FileSystemGZipFile(fileEntity); break;
            case FileType.bzip2: yield FileSystemBZip2File(fileEntity); break;
            case FileType.text: yield FileSystemUTF8TextFile(fileEntity); break;
            case FileType.latin1Text: yield FileSystemLatin1TextFile(fileEntity); break;
            case FileType.metadata: break; // ignore this file
          }
        }
      }
    }
  }
}

class FileSystemLink extends IoNode implements Link {
  FileSystemLink(this._link);

  final io.Link _link;

  @override
  String get name => path.basename(_link.path);

  @override
  String get fullName => _link.path;
}

class FileSystemFile extends IoNode implements File {
  FileSystemFile(this._file);

  final io.File _file;

  @override
  String get name => path.basename(_file.path);

  @override
  String get fullName => _file.path;

  @override
  List<int> readBytes() {
    return cache(BytesOf(_file), () => _file.readAsBytesSync());
  }
}

class FileSystemUTF8TextFile extends FileSystemFile with UTF8TextFile {
  FileSystemUTF8TextFile(io.File file) : super(file);
}

class FileSystemLatin1TextFile extends FileSystemFile with Latin1TextFile {
  FileSystemLatin1TextFile(io.File file) : super(file);
}

class FileSystemZipFile extends FileSystemFile with ZipFile {
  FileSystemZipFile(io.File file) : super(file);
}

class FileSystemTarFile extends FileSystemFile with TarFile {
  FileSystemTarFile(io.File file) : super(file);
}

class FileSystemGZipFile extends FileSystemFile with GZipFile {
  FileSystemGZipFile(io.File file) : super(file);
}

class FileSystemBZip2File extends FileSystemFile with BZip2File {
  FileSystemBZip2File(io.File file) : super(file);
}


// ARCHIVES

class ArchiveDirectory extends IoNode implements Directory {
  ArchiveDirectory(this.fullName, this.name);

  @override
  final String fullName;

  @override
  final String name;

  final Map<String, ArchiveDirectory> _subdirectories = SplayTreeMap<String, ArchiveDirectory>();
  final List<ArchiveFile> _files = <ArchiveFile>[];

  void _add(a.ArchiveFile entry, List<String> remainingPath) {
    if (remainingPath.length > 1) {
      final String subdirectoryName = remainingPath.removeAt(0);
      _subdirectories.putIfAbsent(
        subdirectoryName,
        () => ArchiveDirectory('$fullName/$subdirectoryName', subdirectoryName)
      )._add(entry, remainingPath);
    } else {
      if (entry.size > 0) {
        final String entryFullName = '$fullName/${path.basename(entry.name)}';
        switch (identifyFile(entry.name, () => entry.content as List<int>)) {
          case FileType.binary: _files.add(ArchiveFile(entryFullName, entry)); break;
          case FileType.zip: _files.add(ArchiveZipFile(entryFullName, entry)); break;
          case FileType.tar: _files.add(ArchiveTarFile(entryFullName, entry)); break;
          case FileType.gz: _files.add(ArchiveGZipFile(entryFullName, entry)); break;
          case FileType.bzip2: _files.add(ArchiveBZip2File(entryFullName, entry)); break;
          case FileType.text: _files.add(ArchiveUTF8TextFile(entryFullName, entry)); break;
          case FileType.latin1Text: _files.add(ArchiveLatin1TextFile(entryFullName, entry)); break;
          case FileType.metadata: break; // ignore this file
        }
      }
    }
  }

  static ArchiveDirectory parseArchive(a.Archive archive, String ownerPath) {
    final ArchiveDirectory root = ArchiveDirectory('$ownerPath!', '');
    for (final a.ArchiveFile file in archive.files) {
      if (file.size > 0) {
        root._add(file, file.name.split('/'));
      }
    }
    return root;
  }

  @override
  Iterable<IoNode> get walk sync* {
    yield* _subdirectories.values;
    yield* _files;
  }
}

class ArchiveFile extends IoNode implements File {
  ArchiveFile(this.fullName, this._file);

  final a.ArchiveFile _file;

  @override
  String get name => path.basename(_file.name);

  @override
  final String fullName;

  @override
  List<int>? readBytes() {
    return _file.content as List<int>?;
  }
}

class ArchiveUTF8TextFile extends ArchiveFile with UTF8TextFile {
  ArchiveUTF8TextFile(String fullName, a.ArchiveFile file) : super(fullName, file);
}

class ArchiveLatin1TextFile extends ArchiveFile with Latin1TextFile {
  ArchiveLatin1TextFile(String fullName, a.ArchiveFile file) : super(fullName, file);
}

class ArchiveZipFile extends ArchiveFile with ZipFile {
  ArchiveZipFile(String fullName, a.ArchiveFile file) : super(fullName, file);
}

class ArchiveTarFile extends ArchiveFile with TarFile {
  ArchiveTarFile(String fullName, a.ArchiveFile file) : super(fullName, file);
}

class ArchiveGZipFile extends ArchiveFile with GZipFile {
  ArchiveGZipFile(String fullName, a.ArchiveFile file) : super(fullName, file);
}

class ArchiveBZip2File extends ArchiveFile with BZip2File {
  ArchiveBZip2File(String fullName, a.ArchiveFile file) : super(fullName, file);
}


// IN-MEMORY FILES (e.g. contents of GZipped files)

class InMemoryFile extends IoNode implements File {
  InMemoryFile(this.fullName, this._bytes);

  static InMemoryFile? parse(String fullName, List<int> bytes) {
    if (bytes.isEmpty) {
      return null;
    }
    switch (identifyFile(fullName, () => bytes)) {
      case FileType.binary: return InMemoryFile(fullName, bytes);
      case FileType.zip: return InMemoryZipFile(fullName, bytes);
      case FileType.tar: return InMemoryTarFile(fullName, bytes);
      case FileType.gz: return InMemoryGZipFile(fullName, bytes);
      case FileType.bzip2: return InMemoryBZip2File(fullName, bytes);
      case FileType.text: return InMemoryUTF8TextFile(fullName, bytes);
      case FileType.latin1Text: return InMemoryLatin1TextFile(fullName, bytes);
      case FileType.metadata: break; // ignore this file
    }
    assert(false);
    return null;
  }

  final List<int> _bytes;

  @override
  String get name => '<data>';

  @override
  final String fullName;

  @override
  List<int> readBytes() => _bytes;
}

class InMemoryUTF8TextFile extends InMemoryFile with UTF8TextFile {
  InMemoryUTF8TextFile(String fullName, List<int> file) : super(fullName, file);
}

class InMemoryLatin1TextFile extends InMemoryFile with Latin1TextFile {
  InMemoryLatin1TextFile(String fullName, List<int> file) : super(fullName, file);
}

class InMemoryZipFile extends InMemoryFile with ZipFile {
  InMemoryZipFile(String fullName, List<int> file) : super(fullName, file);
}

class InMemoryTarFile extends InMemoryFile with TarFile {
  InMemoryTarFile(String fullName, List<int> file) : super(fullName, file);
}

class InMemoryGZipFile extends InMemoryFile with GZipFile {
  InMemoryGZipFile(String fullName, List<int> file) : super(fullName, file);
}

class InMemoryBZip2File extends InMemoryFile with BZip2File {
  InMemoryBZip2File(String fullName, List<int> file) : super(fullName, file);
}
