// Copyright 2016 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' show BASE64, UTF8;
import 'dart:io';

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

import 'dart/package_map.dart';
import 'asset.dart';
import 'globals.dart';
import 'observatory.dart';

// A file that has been added to a DevFS.
class DevFSEntry {
  DevFSEntry(this.devicePath, this.file)
      : bundleEntry = null;

  DevFSEntry.bundle(this.devicePath, AssetBundleEntry bundleEntry)
      : bundleEntry = bundleEntry,
        file = bundleEntry.file;

  final String devicePath;
  final AssetBundleEntry bundleEntry;

  final File file;
  FileStat _fileStat;
  // When we updated the DevFS, did we see this entry?
  bool _wasSeen = false;
  DateTime get lastModified => _fileStat?.modified;
  bool get stillExists {
    if (_isSourceEntry)
      return true;
    _stat();
    return _fileStat.type != FileSystemEntityType.NOT_FOUND;
  }
  bool get isModified {
    if (_isSourceEntry)
      return true;

    if (_fileStat == null) {
      _stat();
      return true;
    }
    FileStat _oldFileStat = _fileStat;
    _stat();
    return _fileStat.modified.isAfter(_oldFileStat.modified);
  }

  void _stat() {
    if (_isSourceEntry)
      return;
    _fileStat = file.statSync();
  }

  bool get _isSourceEntry => file == null;

  Future<List<int>> contentsAsBytes() async {
    if (_isSourceEntry)
      return bundleEntry.contentsAsBytes();
    return file.readAsBytes();
  }
}


/// Abstract DevFS operations interface.
abstract class DevFSOperations {
  Future<Uri> create(String fsName);
  Future<dynamic> destroy(String fsName);
  Future<dynamic> writeFile(String fsName, DevFSEntry entry);
  Future<dynamic> deleteFile(String fsName, DevFSEntry entry);
  Future<dynamic> writeSource(String fsName,
                              String devicePath,
                              String contents);
}

/// An implementation of [DevFSOperations] that speaks to the
/// service protocol.
class ServiceProtocolDevFSOperations implements DevFSOperations {
  final Observatory  serviceProtocol;

  ServiceProtocolDevFSOperations(this.serviceProtocol);

  @override
  Future<Uri> create(String fsName) async {
    Response response = await serviceProtocol.createDevFS(fsName);
    return Uri.parse(response['uri']);
  }

  @override
  Future<dynamic> destroy(String fsName) async {
    await serviceProtocol.sendRequest('_deleteDevFS',
                                      <String, dynamic> { 'fsName': fsName });
  }

  @override
  Future<dynamic> writeFile(String fsName, DevFSEntry entry) async {
    List<int> bytes;
    try {
      bytes = await entry.contentsAsBytes();
    } catch (e) {
      return e;
    }
    String fileContents = BASE64.encode(bytes);
    try {
      return await serviceProtocol.sendRequest('_writeDevFSFile',
                                               <String, dynamic> {
                                                  'fsName': fsName,
                                                  'path': entry.devicePath,
                                                  'fileContents': fileContents
                                               });
    } catch (e) {
      printTrace('DevFS: Failed to write ${entry.devicePath}: $e');
    }
  }

  @override
  Future<dynamic> deleteFile(String fsName, DevFSEntry entry) async {
    // TODO(johnmccutchan): Add file deletion to the devFS protocol.
  }

  @override
  Future<dynamic> writeSource(String fsName,
                              String devicePath,
                              String contents) async {
    String fileContents = BASE64.encode(UTF8.encode(contents));
    return await serviceProtocol.sendRequest('_writeDevFSFile',
                                             <String, dynamic> {
                                                'fsName': fsName,
                                                'path': devicePath,
                                                'fileContents': fileContents
                                             });
  }
}

class DevFS {
  /// Create a [DevFS] named [fsName] for the local files in [directory].
  DevFS(Observatory serviceProtocol,
        this.fsName,
        this.rootDirectory)
    : _operations = new ServiceProtocolDevFSOperations(serviceProtocol);

  DevFS.operations(this._operations,
                   this.fsName,
                   this.rootDirectory);

  final DevFSOperations _operations;
  final String fsName;
  final Directory rootDirectory;
  final Map<String, DevFSEntry> _entries = <String, DevFSEntry>{};
  final List<Future<Response>> _pendingWrites = new List<Future<Response>>();
  Uri _baseUri;
  Uri get baseUri => _baseUri;

  Future<Uri> create() async {
    _baseUri = await _operations.create(fsName);
    printTrace('DevFS: Created new filesystem on the device ($_baseUri)');
    return _baseUri;
  }

  Future<dynamic> destroy() async {
    printTrace('DevFS: Deleted filesystem on the device ($_baseUri)');
    return await _operations.destroy(fsName);
  }

  Future<dynamic> update([AssetBundle bundle = null]) async {
    // Mark all entries as not seen.
    _entries.forEach((String path, DevFSEntry entry) {
      entry._wasSeen = false;
    });
    printTrace('DevFS: Starting sync from $rootDirectory');
    // Send the root and lib directories.
    Directory directory = rootDirectory;
    _syncDirectory(directory, recursive: true);
    String packagesFilePath = path.join(rootDirectory.path, kPackagesFileName);
    StringBuffer sb;
    // Send the packages.
    if (FileSystemEntity.isFileSync(packagesFilePath)) {
      PackageMap packageMap = new PackageMap(kPackagesFileName);

      for (String packageName in packageMap.map.keys) {
        Uri uri = packageMap.map[packageName];
        // Ignore self-references.
        if (uri.toString() == 'lib/')
          continue;
        Directory directory = new Directory.fromUri(uri);
        if (_syncDirectory(directory,
                           directoryName: 'packages/$packageName',
                           recursive: true)) {
          if (sb == null) {
            sb = new StringBuffer();
          }
          sb.writeln('$packageName:packages/$packageName');
        }
      }
    }
    if (bundle != null) {
      // Synchronize asset bundle.
      for (AssetBundleEntry entry in bundle.entries) {
        // We write the assets into 'build/flx' so that they are in the
        // same location in DevFS and the iOS simulator.
        final String devicePath = path.join('build/flx', entry.archivePath);
        _syncBundleEntry(devicePath, entry);
      }
    }
    // Handle deletions.
    final List<String> toRemove = new List<String>();
    _entries.forEach((String path, DevFSEntry entry) {
      if (!entry._wasSeen) {
        _deleteEntry(path, entry);
        toRemove.add(path);
      }
    });
    for (int i = 0; i < toRemove.length; i++) {
      _entries.remove(toRemove[i]);
    }
    // Send the assets.
    printTrace('DevFS: Waiting for sync of ${_pendingWrites.length} files '
               'to finish');
    await Future.wait(_pendingWrites);
    _pendingWrites.clear();
    if (sb != null) {
      await _operations.writeSource(fsName, '.packages', sb.toString());
    }
    printTrace('DevFS: Sync finished');
    // NB: You must call flush after a printTrace if you want to be printed
    // immediately.
    logger.flush();
  }

  void _deleteEntry(String path, DevFSEntry entry) {
    _pendingWrites.add(_operations.deleteFile(fsName, entry));
  }

  void _syncFile(String devicePath, File file) {
    DevFSEntry entry = _entries[devicePath];
    if (entry == null) {
      // New file.
      entry = new DevFSEntry(devicePath, file);
      _entries[devicePath] = entry;
    }
    entry._wasSeen = true;
    bool needsWrite = entry.isModified;
    if (needsWrite) {
      Future<dynamic> pendingWrite = _operations.writeFile(fsName, entry);
      if (pendingWrite != null) {
        _pendingWrites.add(pendingWrite);
      } else {
        printTrace('DevFS: Failed to sync "$devicePath"');
      }
    }
  }

  void _syncBundleEntry(String devicePath, AssetBundleEntry assetBundleEntry) {
    DevFSEntry entry = _entries[devicePath];
    if (entry == null) {
      // New file.
      entry = new DevFSEntry.bundle(devicePath, assetBundleEntry);
      _entries[devicePath] = entry;
    }
    entry._wasSeen = true;
    Future<dynamic> pendingWrite = _operations.writeFile(fsName, entry);
    if (pendingWrite != null) {
      _pendingWrites.add(pendingWrite);
    } else {
      printTrace('DevFS: Failed to sync "$devicePath"');
    }
  }

  bool _shouldIgnore(String devicePath) {
    List<String> ignoredPrefixes = <String>['android/',
                                            'build/',
                                            'ios/',
                                            'packages/analyzer'];
    for (String ignoredPrefix in ignoredPrefixes) {
      if (devicePath.startsWith(ignoredPrefix))
        return true;
    }
    return false;
  }

  bool _syncDirectory(Directory directory,
                      {String directoryName,
                       bool recursive: false,
                       bool ignoreDotFiles: true}) {
    String prefix = directoryName;
    if (prefix == null) {
      prefix = path.relative(directory.path, from: rootDirectory.path);
      if (prefix == '.')
        prefix = '';
    }
    try {
      List<FileSystemEntity> files =
          directory.listSync(recursive: recursive, followLinks: false);
      for (FileSystemEntity file in files) {
        if (file is! File) {
          // Skip non-files.
          continue;
        }
        if (ignoreDotFiles && path.basename(file.path).startsWith('.')) {
          // Skip dot files.
          continue;
        }
        final String devicePath =
            path.join(prefix, path.relative(file.path, from: directory.path));
        if (!_shouldIgnore(devicePath))
          _syncFile(devicePath, file);
      }
    } catch (e) {
      // Ignore directory and error.
      return false;
    }
    return true;
  }
}
