// Copyright (c) 2019, 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.

// @dart = 2.10

import 'package:kernel/ast.dart' as ir;
import 'package:kernel/type_environment.dart' as ir;

import 'package:front_end/src/api_unstable/dart2js.dart' as ir
    show LocatedMessage;

import '../diagnostics/diagnostic_listener.dart';
import '../diagnostics/messages.dart';
import '../diagnostics/source_span.dart';
import '../ir/impact_data.dart';
import '../ir/static_type.dart';
import '../js_backend/annotations.dart';
import '../kernel/element_map.dart';
import '../serialization/serialization_interfaces.dart';
import '../util/enumset.dart';
import 'annotations.dart';
import 'impact.dart';
import 'scope.dart';

export 'modular_migrated.dart';

class ModularMemberData {
  final ScopeModel scopeModel;
  final ImpactBuilderData impactBuilderData;

  ModularMemberData(this.scopeModel, this.impactBuilderData);
}

abstract class ModularStrategy {
  List<PragmaAnnotationData> getPragmaAnnotationData(ir.Member node);

  // TODO(johnniwinther): Avoid the need for passing [pragmaAnnotations].
  ModularMemberData getModularMemberData(
      ir.Member node, EnumSet<PragmaAnnotation> pragmaAnnotations);
}

/// [ModuleData] is the data computed modularly, i.e. modularly computed impact
/// data. Currently, we aggregate this data when computing the closed world, so it
/// reflects all of the modularly computed data across the entire program.
class ModuleData {
  static const String tag = 'ModuleData';

  // TODO(joshualitt) Support serializing ModularMemberData;
  final Map<Uri, Map<ir.Member, ImpactBuilderData>> impactData;

  ModuleData([Map<Uri, Map<ir.Member, ImpactBuilderData>> impactData])
      : this.impactData = impactData ?? {};

  factory ModuleData.fromImpactData(
          Map<Uri, Map<ir.Member, ImpactBuilderData>> impactData) =>
      ModuleData(impactData);

  ModuleData readMoreFromDataSource(DataSourceReader source) {
    source.begin(tag);
    int uriCount = source.readInt();
    for (int i = 0; i < uriCount; i++) {
      Uri uri = source.readUri();
      impactData[uri] = source
          .readMemberNodeMap(() => ImpactBuilderData.fromDataSource(source));
    }
    source.end(tag);
    return this;
  }

  factory ModuleData.fromDataSource(DataSourceReader source) =>
      ModuleData().readMoreFromDataSource(source);

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeInt(impactData.keys.length);
    impactData.forEach((uri, data) {
      sink.writeUri(uri);
      sink.writeMemberNodeMap<ImpactBuilderData>(
          data, (e) => e.toDataSink(sink));
    });
    sink.end(tag);
  }
}

/// Compute [ModularMemberData] from the IR.
ModularMemberData computeModularMemberData(
    KernelToElementMap elementMap,
    ir.Member node,
    ScopeModel scopeModel,
    EnumSet<PragmaAnnotation> annotations) {
  var staticTypeCache = StaticTypeCacheImpl();
  var impactBuilderData = ImpactBuilder(
          elementMap,
          ir.StaticTypeContext(node, elementMap.typeEnvironment,
              cache: staticTypeCache),
          staticTypeCache,
          elementMap.classHierarchy,
          scopeModel.variableScopeModel,
          useAsserts: elementMap.options.enableUserAssertions,
          inferEffectivelyFinalVariableTypes:
              !annotations.contains(PragmaAnnotation.disableFinal))
      .computeImpact(node);
  return ModularMemberData(scopeModel, impactBuilderData);
}

void reportLocatedMessage(DiagnosticReporter reporter,
    ir.LocatedMessage message, List<ir.LocatedMessage> context) {
  DiagnosticMessage diagnosticMessage =
      _createDiagnosticMessage(reporter, message);
  var infos = <DiagnosticMessage>[];
  for (ir.LocatedMessage message in context) {
    infos.add(_createDiagnosticMessage(reporter, message));
  }
  reporter.reportError(diagnosticMessage, infos);
}

DiagnosticMessage _createDiagnosticMessage(
    DiagnosticReporter reporter, ir.LocatedMessage message) {
  var sourceSpan = SourceSpan(
      message.uri, message.charOffset, message.charOffset + message.length);
  return reporter.createMessage(
      sourceSpan, MessageKind.GENERIC, {'text': message.problemMessage});
}
