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

/// Converters and codecs for converting between Protobuf and [Info] classes.

import 'dart:convert';
import 'package:fixnum/fixnum.dart';

import 'info.dart';
import 'src/proto/info.pb.dart';

export 'src/proto/info.pb.dart';

class ProtoToAllInfoConverter extends Converter<AllInfoPB, AllInfo> {
  AllInfo convert(AllInfoPB info) {
    // TODO(lorenvs): Implement this conversion. It is unlikely to to be used
    // by production code since the goal of the proto codec is to consume this
    // information from other languages. However, it is useful for roundtrip
    // testing, so we should support it.
    throw new UnimplementedError('ProtoToAllInfoConverter is not implemented');
  }
}

class AllInfoToProtoConverter extends Converter<AllInfo, AllInfoPB> {
  AllInfoPB convert(AllInfo info) => _convertToAllInfoPB(info);

  static DependencyInfoPB _convertToDependencyInfoPB(DependencyInfo info) {
    return new DependencyInfoPB()
      ..targetId = info.target?.serializedId
      ..mask = info.mask;
  }

  static ParameterInfoPB _convertToParameterInfoPB(ParameterInfo info) {
    return new ParameterInfoPB()
      ..name = info.name
      ..type = info.type
      ..declaredType = info.declaredType;
  }

  static MeasurementsPB _convertToMeasurementsPB(Measurements measurements) {
    final proto = new MeasurementsPB();

    if (measurements.uri != null) {
      proto.sourceFile = measurements.uri.toString();
    }

    measurements.entries.forEach((metric, values) {
      final entryProto = new MeasurementEntryPB()..name = metric.name;

      for (final entry in values) {
        entryProto.values.add(entry.begin);
        entryProto.values.add(entry.end);
      }

      proto.entries.add(entryProto);
    });

    measurements.counters.forEach((metric, value) {
      proto.counters.add(new MeasurementCounterPB()
        ..name = metric.name
        ..value = value);
    });

    return proto;
  }

  static LibraryInfoPB _convertToLibraryInfoPB(LibraryInfo info) {
    final proto = new LibraryInfoPB()..uri = info.uri.toString();

    proto.childrenIds
        .addAll(info.topLevelFunctions.map((func) => func.serializedId));
    proto.childrenIds
        .addAll(info.topLevelVariables.map((field) => field.serializedId));
    proto.childrenIds.addAll(info.classes.map((clazz) => clazz.serializedId));
    proto.childrenIds.addAll(info.typedefs.map((def) => def.serializedId));

    return proto;
  }

  static ClassInfoPB _convertToClassInfoPB(ClassInfo info) {
    final proto = new ClassInfoPB()..isAbstract = info.isAbstract;

    proto.childrenIds.addAll(info.functions.map((func) => func.serializedId));
    proto.childrenIds.addAll(info.fields.map((field) => field.serializedId));

    return proto;
  }

  static FunctionModifiersPB _convertToFunctionModifiers(
      FunctionModifiers modifiers) {
    return new FunctionModifiersPB()
      ..isStatic = modifiers.isStatic
      ..isConst = modifiers.isConst
      ..isFactory = modifiers.isFactory
      ..isExternal = modifiers.isExternal;
  }

  static FunctionInfoPB _convertToFunctionInfoPB(FunctionInfo info) {
    final proto = new FunctionInfoPB()
      ..functionModifiers = _convertToFunctionModifiers(info.modifiers)
      ..inlinedCount = info.inlinedCount ?? 0;

    if (info.returnType != null) {
      proto.returnType = info.returnType;
    }

    if (info.inferredReturnType != null) {
      proto.inferredReturnType = info.inferredReturnType;
    }

    if (info.code != null) {
      proto.code = info.code;
    }

    if (info.sideEffects != null) {
      proto.sideEffects = info.sideEffects;
    }

    if (info.measurements != null) {
      proto.measurements = _convertToMeasurementsPB(info.measurements);
    }

    proto.childrenIds
        .addAll(info.closures.map(((closure) => closure.serializedId)));
    proto.parameters.addAll(info.parameters.map(_convertToParameterInfoPB));

    return proto;
  }

  static FieldInfoPB _convertToFieldInfoPB(FieldInfo info) {
    final proto = new FieldInfoPB()
      ..type = info.type
      ..inferredType = info.inferredType
      ..isConst = info.isConst;

    if (info.code != null) {
      proto.code = info.code;
    }

    if (info.initializer != null) {
      proto.initializerId = info.initializer.serializedId;
    }

    proto.childrenIds
        .addAll(info.closures.map((closure) => closure.serializedId));

    return proto;
  }

  static ConstantInfoPB _convertToConstantInfoPB(ConstantInfo info) {
    return new ConstantInfoPB()..code = info.code;
  }

  static OutputUnitInfoPB _convertToOutputUnitInfoPB(OutputUnitInfo info) {
    final proto = new OutputUnitInfoPB();
    proto.imports.addAll(info.imports.where((import) => import != null));
    return proto;
  }

  static TypedefInfoPB _convertToTypedefInfoPB(TypedefInfo info) {
    return new TypedefInfoPB()..type = info.type;
  }

  static ClosureInfoPB _convertToClosureInfoPB(ClosureInfo info) {
    return new ClosureInfoPB()..functionId = info.function.serializedId;
  }

  static InfoPB _convertToInfoPB(Info info) {
    final proto = new InfoPB()
      ..id = info.id
      ..serializedId = info.serializedId
      ..size = info.size;

    if (info.name != null) {
      proto.name = info.name;
    }

    if (info.parent != null) {
      proto.parentId = info.parent.serializedId;
    }

    if (info.coverageId != null) {
      proto.coverageId = info.coverageId;
    }

    if (info is BasicInfo && info.outputUnit != null) {
      // TODO(lorenvs): Similar to the JSON codec, omit this for the default
      // output unit. At the moment, there is no easy way to identify which
      // output unit is the default on [OutputUnitInfo].
      proto.outputUnitId = info.outputUnit.serializedId;
    }

    if (info is CodeInfo) {
      proto.uses.addAll(info.uses.map(_convertToDependencyInfoPB));
    }

    if (info is LibraryInfo) {
      proto.libraryInfo = _convertToLibraryInfoPB(info);
    } else if (info is ClassInfo) {
      proto.classInfo = _convertToClassInfoPB(info);
    } else if (info is FunctionInfo) {
      proto.functionInfo = _convertToFunctionInfoPB(info);
    } else if (info is FieldInfo) {
      proto.fieldInfo = _convertToFieldInfoPB(info);
    } else if (info is ConstantInfo) {
      proto.constantInfo = _convertToConstantInfoPB(info);
    } else if (info is OutputUnitInfo) {
      proto.outputUnitInfo = _convertToOutputUnitInfoPB(info);
    } else if (info is TypedefInfo) {
      proto.typedefInfo = _convertToTypedefInfoPB(info);
    } else if (info is ClosureInfo) {
      proto.closureInfo = _convertToClosureInfoPB(info);
    }

    return proto;
  }

  static ProgramInfoPB _convertToProgramInfoPB(ProgramInfo info) {
    return new ProgramInfoPB()
      ..entrypointId = info.entrypoint.serializedId
      ..size = info.size
      ..dart2jsVersion = info.dart2jsVersion
      ..compilationMoment =
          new Int64(info.compilationMoment.microsecondsSinceEpoch)
      ..compilationDuration = new Int64(info.compilationDuration.inMicroseconds)
      ..toProtoDuration = new Int64(info.toJsonDuration.inMicroseconds)
      ..dumpInfoDuration = new Int64(info.dumpInfoDuration.inMicroseconds)
      ..noSuchMethodEnabled = info.noSuchMethodEnabled ?? false
      ..isRuntimeTypeUsed = info.isRuntimeTypeUsed ?? false
      ..isIsolateUsed = info.isIsolateInUse ?? false
      ..isFunctionApplyUsed = info.isFunctionApplyUsed ?? false
      ..isMirrorsUsed = info.isMirrorsUsed ?? false
      ..minified = info.minified ?? false;
  }

  static Iterable<AllInfoPB_AllInfosEntry>
      _convertToAllInfosEntries<T extends Info>(Iterable<T> infos) sync* {
    for (final info in infos) {
      final infoProto = _convertToInfoPB(info);
      final entry = new AllInfoPB_AllInfosEntry()
        ..key = infoProto.serializedId
        ..value = infoProto;
      yield entry;
    }
  }

  static LibraryDeferredImportsPB _convertToLibraryDeferredImportsPB(
      String libraryUri, Map<String, dynamic> fields) {
    final proto = new LibraryDeferredImportsPB()
      ..libraryUri = libraryUri
      ..libraryName = fields['name'] ?? '<unnamed>';

    Map<String, List<String>> imports = fields['imports'];
    imports.forEach((prefix, files) {
      final import = new DeferredImportPB()..prefix = prefix;
      import.files.addAll(files);
      proto.imports.add(import);
    });

    return proto;
  }

  static AllInfoPB _convertToAllInfoPB(AllInfo info) {
    final proto = new AllInfoPB()
      ..program = _convertToProgramInfoPB(info.program);

    proto.allInfos.addAll(_convertToAllInfosEntries(info.libraries));
    proto.allInfos.addAll(_convertToAllInfosEntries(info.classes));
    proto.allInfos.addAll(_convertToAllInfosEntries(info.functions));
    proto.allInfos.addAll(_convertToAllInfosEntries(info.fields));
    proto.allInfos.addAll(_convertToAllInfosEntries(info.constants));
    proto.allInfos.addAll(_convertToAllInfosEntries(info.outputUnits));
    proto.allInfos.addAll(_convertToAllInfosEntries(info.typedefs));
    proto.allInfos.addAll(_convertToAllInfosEntries(info.closures));

    info.deferredFiles?.forEach((libraryUri, fields) {
      proto.deferredImports
          .add(_convertToLibraryDeferredImportsPB(libraryUri, fields));
    });

    return proto;
  }
}

/// A codec for converting [AllInfo] to a protobuf format.
///
/// This codec is still experimental, and will likely crash on certain output
/// from dart2js.
class AllInfoProtoCodec extends Codec<AllInfo, AllInfoPB> {
  final Converter<AllInfo, AllInfoPB> encoder = new AllInfoToProtoConverter();
  final Converter<AllInfoPB, AllInfo> decoder = new ProtoToAllInfoConverter();
}
