// 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.

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

import 'package:dwds/src/readers/asset_reader.dart';
import 'package:logging/logging.dart';
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;

/// A reader for Dart sources and related source maps provided by the Frontend
/// Server.
class FrontendServerAssetReader implements AssetReader {
  final _logger = Logger('FrontendServerAssetReader');
  final File _mapOriginal;
  final File _mapIncremental;
  final File _jsonOriginal;
  final File _jsonIncremental;
  final String _packageRoot;
  final Future<PackageConfig> _packageConfig;
  final String _basePath;

  /// Map of Dart module server path to source map contents.
  final _mapContents = <String, String>{};

  bool _haveReadOriginals = false;

  /// Creates a [FrontendServerAssetReader].
  ///
  /// [outputPath] is the file path to the Frontend Server kernel file e.g.
  ///
  ///   /some/path/main.dart.dill
  ///
  /// Corresponding `.json` and `.map` files will be read relative to
  /// [outputPath].
  ///
  /// [_packageRoot] is the path to the directory that contains a
  /// `.dart_tool/package_config.json` file for the application.
  FrontendServerAssetReader({
    required String outputPath,
    required String packageRoot,
    String? basePath,
  }) : _packageRoot = packageRoot,
       _basePath = basePath ?? '',
       _mapOriginal = File('$outputPath.map'),
       _mapIncremental = File('$outputPath.incremental.map'),
       _jsonOriginal = File('$outputPath.json'),
       _jsonIncremental = File('$outputPath.incremental.json'),
       _packageConfig = loadPackageConfig(
         File(
           p.absolute(p.join(packageRoot, '.dart_tool/package_config.json')),
         ),
       );

  @override
  String get basePath => _basePath;

  @override
  Future<String?> dartSourceContents(String serverPath) async {
    if (serverPath.endsWith('.dart')) {
      final packageConfig = await _packageConfig;

      Uri? fileUri;
      if (serverPath.startsWith('packages/')) {
        final packagePath = serverPath.replaceFirst('packages/', 'package:');
        fileUri = packageConfig.resolve(Uri.parse(packagePath));
      } else {
        fileUri = p.toUri(p.join(_packageRoot, serverPath));
      }
      if (fileUri != null) {
        final source = File(fileUri.toFilePath());
        if (source.existsSync()) return source.readAsString();
      }
    }
    _logger.severe('Cannot find source contents for $serverPath');
    return null;
  }

  @override
  Future<String?> sourceMapContents(String serverPath) async {
    if (serverPath.endsWith('lib.js.map')) {
      if (!serverPath.startsWith('/')) serverPath = '/$serverPath';
      // Strip the .map, sources are looked up by their js path.
      serverPath = p.withoutExtension(serverPath);
      if (_mapContents.containsKey(serverPath)) {
        return _mapContents[serverPath];
      }
    }
    _logger.severe('Cannot find source map contents for $serverPath');
    return null;
  }

  /// Updates the internal caches by reading the Frontend Server output files.
  ///
  /// Will only read the incremental files on additional calls.
  void updateCaches() {
    if (!_haveReadOriginals) {
      _updateCaches(_mapOriginal, _jsonOriginal);
      _haveReadOriginals = true;
    } else {
      _updateCaches(_mapIncremental, _jsonIncremental);
    }
  }

  void _updateCaches(File map, File json) {
    if (!(map.existsSync() && json.existsSync())) {
      throw StateError('$map and $json do not exist.');
    }
    final sourceContents = map.readAsBytesSync();
    final sourceInfo =
        jsonDecode(json.readAsStringSync()) as Map<String, dynamic>;
    for (final key in sourceInfo.keys) {
      final info = sourceInfo[key];
      _mapContents[key] = utf8.decode(
        sourceContents
            .getRange(info['sourcemap'][0] as int, info['sourcemap'][1] as int)
            .toList(),
      );
    }
  }

  @override
  Future<String> metadataContents(String serverPath) {
    // TODO(grouma) - Implement the merged metadata reader.
    throw UnimplementedError();
  }

  @override
  Future<void> close() async {}
}
