// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Utilities for downloading and locally caching symbol files.
library symbolizer.symbols;

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;

import 'package:symbolizer/model.dart';
import 'package:symbolizer/ndk.dart';

final _log = Logger('symbols');

/// Local cache of symbol files downloaded from Cloud Storage bucket.
class SymbolsCache {
  final Ndk _ndk;

  /// Local path at which this cache is located.
  final String _path;

  /// Number of entries in the cache after which we will start trying to
  /// evict all entries which were not touched for longer than
  /// [evictionThreshold].
  final int _sizeThreshold;

  /// Threshold past which an unused entry in the cache is considered evictable.
  final Duration _evictionThreshold;

  /// Map describing when symbols for the given [EngineBuild] were used
  /// last time.
  final Map<String, int> _lastUsedTimestamp = {};

  /// Cache mapping Build-Id's values to corresponding engine builds.
  final Map<String, EngineBuild> _buildIdCache = {};

  /// Pending downloads by [EngineBuild].
  final Map<String, Future<String>> _downloads = {};

  /// Constructs cache at the given [path], which is assumed to be a directory.
  /// If destination does not exist it will be created.
  SymbolsCache({
    @required Ndk ndk,
    @required String path,
    int sizeThreshold = 20,
    Duration evictionThreshold = const Duration(minutes: 5),
  })  : _ndk = ndk,
        _path = path,
        _sizeThreshold = sizeThreshold,
        _evictionThreshold = evictionThreshold {
    if (!Directory(path).existsSync()) {
      Directory(path).createSync();
    }
    _loadState();
  }

  /// If necessary download symbols for the given [build] and return path to
  /// the folder containing them.
  Future<String> get(EngineBuild build) => _get(build, '', _downloadSymbols);

  /// If necessary download engine binary (libflutter.so or Flutter) for the
  /// given build and return path to the binary itself.
  Future<String> getEngineBinary(EngineBuild build) async {
    final dir = await _get(build, 'libflutter', _downloadEngine);
    return p.join(dir, p.basename(_libflutterPath(build)));
  }

  /// Download an artifact from Cloud Storage using the given [downloader] and
  /// cache result in the path using the given [suffix].
  Future<String> _get(
    EngineBuild build,
    String suffix,
    Future<void> Function(Directory, EngineBuild) downloader,
  ) {
    final cacheDir = _cacheDirectoryFor(build, suffix: suffix);
    if (!_downloads.containsKey(cacheDir)) {
      _downloads[cacheDir] = _getImpl(cacheDir, build, downloader);
      _downloads[cacheDir].then((_) => _downloads.remove(cacheDir));
    }
    return _downloads[cacheDir];
  }

  /// Given the [engineHash] and [EngineVariant] which specifies OS and
  /// architecture look at symbols for all possible build modes and
  /// find the one matching the given [buildId].
  ///
  /// Currently only used for Android symbols because on iOS LC_UUID
  /// is unreliable.
  Future<EngineBuild> findVariantByBuildId({
    @required String engineHash,
    @required EngineVariant variant,
    @required String buildId,
  }) async {
    _log.info('looking for ${buildId} among ${variant} engines');
    if (variant.os != 'android') {
      throw ArgumentError(
          'LC_UUID is unreliable on iOS and can not be used for mode matching');
    }

    // Check if we already have a match in the Build-Id cache.
    if (_buildIdCache.containsKey(buildId)) {
      final build = _buildIdCache[buildId];
      if (build.variant.os == variant.os &&
          build.variant.arch == variant.arch) {
        return build;
      }
    }

    for (var potentialVariant in EngineVariant.allModesFor(variant)) {
      final engineBuild =
          EngineBuild(engineHash: engineHash, variant: potentialVariant);
      final dir = await get(engineBuild);
      final thisBuildId = await _ndk.getBuildId(p.join(dir, 'libflutter.so'));
      _buildIdCache[thisBuildId] = engineBuild;
      if (thisBuildId == buildId) {
        return engineBuild;
      }
    }
    throw 'Failed to find build with matching buildId (${buildId})';
  }

  File get _cacheStateFile => File(p.join(_path, 'cache.json'));

  void _loadState() {
    if (!_cacheStateFile.existsSync()) return;

    final Map<String, dynamic> cacheState =
        jsonDecode(_cacheStateFile.readAsStringSync());
    final timestamps = cacheState['lastUsedTimestamp'] as List<dynamic>;
    _lastUsedTimestamp.clear();
    for (var i = 0; i < timestamps.length; i += 2) {
      _lastUsedTimestamp[timestamps[i]] = timestamps[i + 1];
    }
    _buildIdCache.addAll((cacheState['buildIdCache'] as Map<String, dynamic>)
        .map((key, value) => MapEntry(key, EngineBuild.fromJson(value))));
  }

  void _saveState() {
    _cacheStateFile.writeAsStringSync(jsonEncode({
      'lastUsedTimestamp':
          _lastUsedTimestamp.entries.expand((e) => [e.key, e.value]).toList(),
      'buildIdCache': _buildIdCache
    }));
  }

  String _cacheDirectoryFor(EngineBuild build, {String suffix = ''}) =>
      'symbols-cache/${build.engineHash}-${build.variant.toArtifactPath()}'
      '${suffix.isNotEmpty ? '-' : ''}${suffix}';

  Future<String> _getImpl(String targetDir, EngineBuild build,
      Future<void> Function(Directory, EngineBuild) downloader) async {
    final dir = Directory(targetDir);
    if (dir.existsSync()) {
      _touch(dir.path);
      return dir.path;
    }

    // Make sure we have some space.
    _evictOldEntriesIfNecessary();
    _log.info('downloading ${targetDir} for ${build}');

    // Download symbols into a temporary directory, once we successfully
    // unpack them we will rename this directory.
    final tempDir = await Directory.systemTemp.createTemp();
    try {
      await downloader(tempDir, build);
      // Now move the directory into the cache.
      final renamed = await tempDir.rename(dir.path);
      if (build.variant.os == 'android') {
        // Fetch Build-Id from the library and add it to the cache.
        final buildId =
            await _ndk.getBuildId(p.join(renamed.path, 'libflutter.so'));
        _buildIdCache[buildId] = build;
      }
      _touch(renamed.path);
      return renamed.path;
    } finally {
      if (tempDir.existsSync()) {
        tempDir.deleteSync(recursive: true);
      }
    }
  }

  Future<void> _downloadSymbols(Directory tempDir, EngineBuild build) async {
    final symbolsFile =
        build.variant.os == 'ios' ? 'Flutter.dSYM.zip' : 'symbols.zip';

    await _run('gsutil', [
      'cp',
      'gs://flutter_infra/flutter/${build.engineHash}/${build.variant.toArtifactPath()}/${symbolsFile}',
      p.join(tempDir.path, symbolsFile)
    ]);
    await _run('unzip', [symbolsFile], workingDirectory: tempDir.path);

    // Delete downloaded ZIP file.
    await File(p.join(tempDir.path, symbolsFile)).delete();
  }

  Future<void> _downloadEngine(Directory tempDir, EngineBuild build) async {
    final artifactsFile = 'artifacts.zip';
    await _run('gsutil', [
      'cp',
      'gs://flutter_infra/flutter/${build.engineHash}/${build.variant.toArtifactPath()}/${artifactsFile}',
      p.join(tempDir.path, artifactsFile)
    ]);

    final nestedZip =
        build.variant.os == 'ios' ? 'Flutter.framework.zip' : 'flutter.jar';

    await _run('unzip', [artifactsFile, nestedZip],
        workingDirectory: tempDir.path);

    final libraryPath = _libflutterPath(build);
    await _run('unzip', [nestedZip, libraryPath],
        workingDirectory: tempDir.path);

    if (p.dirname(libraryPath) != '.') {
      await File(p.join(tempDir.path, libraryPath))
          .rename(p.join(tempDir.path, p.basename(libraryPath)));
      await Directory(p.join(tempDir.path, p.dirname(libraryPath)))
          .delete(recursive: true);
    }

    // Delete downloaded ZIP file.
    await File(p.join(tempDir.path, artifactsFile)).delete();
    await File(p.join(tempDir.path, nestedZip)).delete();
  }

  static String _libflutterPath(EngineBuild build) {
    switch (build.variant.os) {
      case 'ios':
        return 'Flutter';
      case 'android':
        switch (build.variant.arch) {
          case 'arm64':
            return 'lib/arm64-v8a/libflutter.so';
          case 'arm':
            return 'lib/armeabi-v7a/libflutter.so';
        }
        break;
    }
    throw 'Unsupported combination of architecture and OS: ${build.variant}';
  }

  Future<void> _run(String executable, List<String> args,
      {String workingDirectory}) async {
    final result =
        await Process.run(executable, args, workingDirectory: workingDirectory);
    if (result.exitCode != 0) {
      throw 'Failed to run ${executable} ${args.join(' ')} '
          '(exit code ${result.exitCode}): ${result.stdout} ${result.stderr}';
    }
  }

  void _touch(String path) {
    _lastUsedTimestamp[path] = DateTime.now().millisecondsSinceEpoch;
    _saveState();
  }

  /// If the cache is too big then evict all entries outside of the given
  /// interval.
  void _evictOldEntriesIfNecessary() {
    if (_lastUsedTimestamp.length < _sizeThreshold) {
      return;
    }

    final fiveMinutesAgo =
        DateTime.now().subtract(_evictionThreshold).millisecondsSinceEpoch;
    for (var path in _lastUsedTimestamp.entries
        .where((e) => e.value < fiveMinutesAgo)
        .map((e) => e.key)
        .toList()) {
      final dir = Directory(path);
      if (dir.existsSync()) {
        dir.deleteSync(recursive: true);
      }
      _lastUsedTimestamp.remove(path);
    }
    _saveState();
  }
}

extension on EngineVariant {
  String toArtifactPath() {
    final modeSuffix = (mode == 'debug') ? '' : '-${mode}';
    if (os == 'ios') {
      return '${os}${modeSuffix}';
    } else {
      return '${os}-${arch}${modeSuffix}';
    }
  }
}
