// Copyright 2015 The Chromium 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:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:bignum/bignum.dart';

import 'signing.dart';

// Magic string we put at the top of all bundle files.
const String kBundleMagic = '#!mojo mojo:flutter\n';

// Prefix of the above, used when reading bundle files. This allows us to be
// more flexbile about what we accept.
const String kBundleMagicPrefix = '#!mojo ';

typedef Stream<List<int>> StreamOpener();

Future<List<int>> _readBytesWithLength(RandomAccessFile file) async {
  ByteData buffer = new ByteData(4);
  await file.readInto(buffer.buffer.asUint8List());
  int length = buffer.getUint32(0, Endianness.LITTLE_ENDIAN);
  return await file.read(length);
}

const int kMaxLineLen = 10*1024;
const int kNewline = 0x0A;
Future<String> _readLine(RandomAccessFile file) async {
  String line = '';
  while (line.length < kMaxLineLen) {
    int byte = await file.readByte();
    if (byte == -1 || byte == kNewline)
      break;
    line += new String.fromCharCode(byte);
  }
  return line;
}

// Writes a 32-bit length followed by the content of [bytes].
void _writeBytesWithLengthSync(RandomAccessFile outputFile, List<int> bytes) {
  if (bytes == null)
    bytes = new Uint8List(0);
  assert(bytes.length < 0xffffffff);
  ByteData length = new ByteData(4)..setUint32(0, bytes.length, Endianness.LITTLE_ENDIAN);
  outputFile.writeFromSync(length.buffer.asUint8List());
  outputFile.writeFromSync(bytes);
}

// Represents a parsed .flx Bundle. Contains information from the bundle's
// header, as well as an open File handle positioned where the zip content
// begins.
// The bundle format is:
// #!mojo <any string>\n
// <32-bit length><signature of the manifest data>
// <32-bit length><manifest data>
// <zip content>
//
// The manifest is a JSON string containing the following keys:
// (optional) name: the name of the package.
// version: the package version.
// update-url: the base URL to download a new manifest and bundle.
// key: a BASE-64 encoded DER-encoded ASN.1 representation of the Q point of the
//   ECDSA public key that was used to sign this manifest.
// content-hash: an integer SHA-256 hash value of the <zip content>.
class Bundle {
  Bundle._fromFile(this.path);
  Bundle.fromContent({
    this.path,
    this.manifest,
    contentBytes,
    AsymmetricKeyPair keyPair
  }) : _contentBytes = contentBytes {
    assert(path != null);
    assert(manifest != null);
    assert(_contentBytes != null);
    manifestBytes = serializeManifest(manifest, keyPair?.publicKey, _contentBytes);
    signatureBytes = signManifest(manifestBytes, keyPair?.privateKey);
    _openContentStream = () => new Stream.fromIterable(<List<int>>[_contentBytes]);
  }

  final String path;
  List<int> signatureBytes;
  List<int> manifestBytes;
  Map<String, dynamic> manifest;

  // Callback to open a Stream containing the bundle content data.
  StreamOpener _openContentStream;

  // Zip content bytes. Only valid when created in memory.
  List<int> _contentBytes;

  Future<bool> _readHeader() async {
    RandomAccessFile file = await new File(path).open();
    String magic = await _readLine(file);
    if (!magic.startsWith(kBundleMagicPrefix)) {
      file.close();
      return false;
    }
    signatureBytes = await _readBytesWithLength(file);
    manifestBytes = await _readBytesWithLength(file);
    int contentOffset = await file.position();
    _openContentStream = () => new File(path).openRead(contentOffset);
    file.close();

    String manifestString = UTF8.decode(manifestBytes);
    manifest = JSON.decode(manifestString);
    return true;
  }

  static Future<Bundle> readHeader(String path) async {
    Bundle bundle = new Bundle._fromFile(path);
    if (!await bundle._readHeader())
      return null;
    return bundle;
  }

  // Verifies that the package has a valid signature and content.
  Future<bool> verifyContent() async {
    if (!verifyManifestSignature(manifest, manifestBytes, signatureBytes))
      return false;

    Stream<List<int>> content = _openContentStream();
    BigInteger expectedHash = new BigInteger(manifest['content-hash'], 10);
    if (!await verifyContentHash(expectedHash, content))
      return false;

    return true;
  }

  // Writes the in-memory representation to disk.
  void writeSync() {
    assert(_contentBytes != null);
    RandomAccessFile outputFile = new File(path).openSync(mode: FileMode.WRITE);
    outputFile.writeStringSync(kBundleMagic);
    _writeBytesWithLengthSync(outputFile, signatureBytes);
    _writeBytesWithLengthSync(outputFile, manifestBytes);
    outputFile.writeFromSync(_contentBytes);
    outputFile.close();
  }
}
