// 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); break;
      case FileType.zip: return InMemoryZipFile(fullName, bytes); break;
      case FileType.tar: return InMemoryTarFile(fullName, bytes); break;
      case FileType.gz: return InMemoryGZipFile(fullName, bytes); break;
      case FileType.bzip2: return InMemoryBZip2File(fullName, bytes); break;
      case FileType.text: return InMemoryUTF8TextFile(fullName, bytes); break;
      case FileType.latin1Text: return InMemoryLatin1TextFile(fullName, bytes); break;
      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);
}
