// 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 'package:dwds/src/debugging/metadata/provider.dart';
import 'package:dwds/src/loaders/strategy.dart';
import 'package:dwds/src/readers/asset_reader.dart';
import 'package:dwds/src/services/expression_compiler.dart';
import 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart';

String removeJsExtension(String path) =>
    path.endsWith('.js') ? p.withoutExtension(path) : path;

String addJsExtension(String path) => '$path.js';

// web/main.ddc.js -> main.ddc.js
// packages/test/test.dart.js -> packages/test/test.dart.js
String stripTopLevelDirectory(String path) =>
    path.startsWith('packages') ? path : path.split('/').skip(1).join('/');

/// JavaScript snippet to determine the base URL of the current path.
const _baseUrlScript = '''
var baseUrl = (function () {
  // Attempt to detect --precompiled mode for tests, and set the base url
  // appropriately, otherwise set it to '/'.
  var pathParts = location.pathname.split("/");
  if (pathParts[0] == "") {
    pathParts.shift();
  }
  if (pathParts.length > 1 && pathParts[1] == "test") {
    return "/" + pathParts.slice(0, 2).join("/") + "/";
  }
  // Attempt to detect base url using <base href> html tag
  // base href should start and end with "/"
  if (typeof document !== 'undefined') {
    var el = document.getElementsByTagName('base');
    if (el && el[0] && el[0].getAttribute("href") && el[0].getAttribute
    ("href").startsWith("/") && el[0].getAttribute("href").endsWith("/")){
      return el[0].getAttribute("href");
    }
  }
  // return default value
  return "/";
}());
''';

/// A load strategy for the require-js module system.
class RequireStrategy extends LoadStrategy {
  @override
  final ReloadConfiguration reloadConfiguration;

  final String _requireDigestsPath = r'$requireDigestsPath';

  /// Returns a map of module name to corresponding server path (excluding .js)
  /// for the provided Dart application entrypoint.
  ///
  /// For example:
  ///
  ///   web/main -> main.ddc
  ///   packages/path/path -> packages/path/path.ddc
  ///
  final Future<Map<String, String>> Function(MetadataProvider metadataProvider)
      _moduleProvider;

  /// Returns a map of module name to corresponding digest value.
  ///
  /// For example:
  ///
  ///   web/main -> 8363b363f74b41cac955024ab8b94a3f
  ///   packages/path/path -> d348c2a4647e998011fe305f74f22961
  ///
  final Future<Map<String, String>> Function(MetadataProvider metadataProvider)
      _digestsProvider;

  /// Returns the module for the corresponding server path.
  ///
  /// For example:
  ///
  /// /packages/path/path.ddc.js -> packages/path/path
  ///
  final Future<String?> Function(MetadataProvider provider, String sourcePath)
      _moduleForServerPath;

  /// Returns the server path for the provided module.
  ///
  /// For example:
  ///
  ///   web/main -> main.ddc.js
  ///
  final Future<String?> Function(MetadataProvider provider, String module)
      _serverPathForModule;

  /// Returns the source map path for the provided module.
  ///
  /// For example:
  ///
  ///   web/main -> main.ddc.js.map
  ///
  final Future<String?> Function(MetadataProvider provider, String module)
      _sourceMapPathForModule;

  /// Returns the server path for the app uri.
  ///
  /// For example:
  ///
  ///   org-dartlang-app://web/main.dart -> main.dart
  ///
  /// Will return `null` if the provided uri is not
  /// an app URI.
  final String? Function(String appUri) _serverPathForAppUri;

  /// Returns a map from module id to module info.
  ///
  /// For example:
  ///
  ///   web/main -> {main.ddc.full.dill, main.ddc.dill}
  ///
  final Future<Map<String, ModuleInfo>> Function(
    MetadataProvider metadataProvider,
  ) _moduleInfoForProvider;

  @override
  BuildSettings get buildSettings => _buildSettings;
  final BuildSettings _buildSettings;

  RequireStrategy(
    this.reloadConfiguration,
    this._moduleProvider,
    this._digestsProvider,
    this._moduleForServerPath,
    this._serverPathForModule,
    this._sourceMapPathForModule,
    this._serverPathForAppUri,
    this._moduleInfoForProvider,
    AssetReader assetReader,
    this._buildSettings,
  ) : super(assetReader);

  @override
  Handler get handler => (request) async {
        if (request.url.path.endsWith(_requireDigestsPath)) {
          final entrypoint = request.url.queryParameters['entrypoint'];
          if (entrypoint == null) return Response.notFound('${request.url}');
          final metadataProvider =
              metadataProviderFor(request.url.queryParameters['entrypoint']!);
          final digests = await _digestsProvider(metadataProvider);
          return Response.ok(json.encode(digests));
        }
        return Response.notFound('${request.url}');
      };

  @override
  String get id => 'require-js';

  @override
  String get moduleFormat => 'amd';

  @override
  String get loadLibrariesModule => 'require.js';

  @override
  String get loadModuleSnippet => 'require';

  /// Require JS config for ddc.
  ///
  /// Sets the base url to `/` so that all modules can be loaded using absolute
  /// paths which simplifies a lot of scenarios.
  ///
  /// Sets the timeout for loading modules to infinity (0).
  ///
  /// Sets up the custom module paths.
  ///
  /// Adds error handler code for require.js which requests a `.errors` file for
  /// any failed module, and logs it to the console.
  String get _requireJsConfig => '''
$_baseUrlScript;
require.config({
    baseUrl: baseUrl,
    waitSeconds: 0,
    paths: modulePaths 
});
const modulesGraph = new Map();
requirejs.onResourceLoad = function (context, map, depArray) {
  const name = map.name;
  const depNameArray = depArray.map((dep) => dep.name);
  if (modulesGraph.has(name)) {
    var previousDeps = modulesGraph.get(name);
    var changed = previousDeps.length != depNameArray.length;
    changed = changed || depNameArray.some(function(depName) {
      return !previousDeps.includes(depName);
    });
    if (changed) {
      console.warn("Dependencies graph change for module '" + name + "' detected. " +
        "Dependencies was [" + previousDeps + "], now [" +  depNameArray.map((depName) => depName) +"]. " +
        "Page can't be hot-reloaded, firing full page reload.");
      window.location.reload();
    }
  } else {
    modulesGraph.set(name, []);
    for (const depName of depNameArray) {
      if (!\$requireLoader.moduleParentsGraph.has(depName)) {
        \$requireLoader.moduleParentsGraph.set(depName, []);
      }
      \$requireLoader.moduleParentsGraph.get(depName).push(name);
      modulesGraph.get(name).push(depName);
    }
  }
};
''';

  @override
  Future<String> bootstrapFor(String entrypoint) async =>
      await _requireLoaderSetup(entrypoint) + _requireJsConfig;

  @override
  String loadClientSnippet(String clientScript) =>
      'window.\$requireLoader.forceLoadModule("$clientScript");\n';

  Future<String> _requireLoaderSetup(String entrypoint) async {
    final metadataProvider = metadataProviderFor(entrypoint);
    final modulePaths = await _moduleProvider(metadataProvider);
    final moduleNames =
        modulePaths.map((key, value) => MapEntry<String, String>(value, key));
    return '''
$_baseUrlScript
let modulePaths = ${const JsonEncoder.withIndent(" ").convert(modulePaths)};
let moduleNames = ${const JsonEncoder.withIndent(" ").convert(moduleNames)};
if(!window.\$requireLoader) {
   window.\$requireLoader = {
     digestsPath: '$_requireDigestsPath?entrypoint=$entrypoint',
     // Used in package:build_runner/src/server/build_updates_client/hot_reload_client.dart
     moduleParentsGraph: new Map(),
     forceLoadModule: function (modulePath, callback, onError) {
       let moduleName = moduleNames[modulePath];
       if (moduleName == null) {
         moduleName = modulePath;
       }
       requirejs.undef(moduleName);
       try{
        requirejs([moduleName], function() {
          if (typeof callback != 'undefined') {
            callback();
          }
        });
       } catch (error) {
        if (typeof onError != 'undefined') {
          onError(error);
        }else{
          throw(error);
        }
       }
     },
     getModuleLibraries: null, // set up by _initializeTools
   };
}
''';
  }

  @override
  Future<String?> moduleForServerPath(String entrypoint, String serverPath) {
    final metadataProvider = metadataProviderFor(entrypoint);
    return _moduleForServerPath(metadataProvider, serverPath);
  }

  @override
  Future<String?> serverPathForModule(String entrypoint, String module) {
    final metadataProvider = metadataProviderFor(entrypoint);
    return _serverPathForModule(metadataProvider, module);
  }

  @override
  Future<String?> sourceMapPathForModule(String entrypoint, String module) {
    final metadataProvider = metadataProviderFor(entrypoint);
    return _sourceMapPathForModule(metadataProvider, module);
  }

  @override
  String? serverPathForAppUri(String appUri) => _serverPathForAppUri(appUri);

  @override
  Future<Map<String, ModuleInfo>> moduleInfoForEntrypoint(String entrypoint) =>
      _moduleInfoForProvider(metadataProviderFor(entrypoint));

  @override
  String? g3RelativePath(String absolutePath) => null;
}
