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

part of '../protoc.dart';

class EnumAlias {
  final EnumValueDescriptorProto value;
  final EnumValueDescriptorProto canonicalValue;
  EnumAlias(this.value, this.canonicalValue);
}

class EnumGenerator extends ProtobufContainer {
  @override
  final ProtobufContainer parent;
  @override
  final String classname;
  @override
  final String fullName;
  final EnumDescriptorProto _descriptor;
  final List<EnumValueDescriptorProto> _canonicalValues =
      <EnumValueDescriptorProto>[];
  final List<int> _originalCanonicalIndices = <int>[];
  final List<EnumAlias> _aliases = <EnumAlias>[];

  /// Maps the name of an enum value to the Dart name we will use for it.
  final Map<String, String> dartNames = <String, String>{};
  final List<int> _originalAliasIndices = <int>[];
  List<int> _fieldPath;
  final List<int> _fieldPathSegment;

  /// See [[ProtobufContainer]
  @override
  List<int> get fieldPath =>
      _fieldPath ??= List.from(parent.fieldPath)..addAll(_fieldPathSegment);

  EnumGenerator._(EnumDescriptorProto descriptor, this.parent,
      Set<String> usedClassNames, int repeatedFieldIndex, int fieldIdTag)
      : assert(parent != null),
        _fieldPathSegment = [fieldIdTag, repeatedFieldIndex],
        classname = messageOrEnumClassName(descriptor.name, usedClassNames,
            parent: parent?.classname ?? ''),
        fullName = parent.fullName == ''
            ? descriptor.name
            : '${parent.fullName}.${descriptor.name}',
        _descriptor = descriptor {
    final usedNames = {...reservedEnumNames};
    for (var i = 0; i < descriptor.value.length; i++) {
      var value = descriptor.value[i];
      var canonicalValue =
          descriptor.value.firstWhere((v) => v.number == value.number);
      if (value == canonicalValue) {
        _canonicalValues.add(value);
        _originalCanonicalIndices.add(i);
      } else {
        _aliases.add(EnumAlias(value, canonicalValue));
        _originalAliasIndices.add(i);
      }
      dartNames[value.name] = disambiguateName(
          avoidInitialUnderscore(value.name), usedNames, enumSuffixes());
    }
  }

  static const _topLevelFieldTag = 5;
  static const _nestedFieldTag = 4;

  EnumGenerator.topLevel(
      EnumDescriptorProto descriptor,
      ProtobufContainer parent,
      Set<String> usedClassNames,
      int repeatedFieldIndex)
      : this._(descriptor, parent, usedClassNames, repeatedFieldIndex,
            _topLevelFieldTag);

  EnumGenerator.nested(EnumDescriptorProto descriptor, ProtobufContainer parent,
      Set<String> usedClassNames, int repeatedFieldIndex)
      : this._(descriptor, parent, usedClassNames, repeatedFieldIndex,
            _nestedFieldTag);

  @override
  String get package => parent.package;
  @override
  FileGenerator get fileGen => parent.fileGen;

  /// Make this enum available as a field type.
  void register(GenerationContext ctx) {
    ctx.registerFieldType(this);
  }

  /// Returns a const expression that evaluates to the JSON for this message.
  /// [usage] represents the .pb.dart file where the expression will be used.
  String getJsonConstant(FileGenerator usage) {
    var name = '$classname\$json';
    if (usage.protoFileUri == fileGen.protoFileUri) {
      return name;
    }
    return '$fileImportPrefix.$name';
  }

  static const int _enumValueTag = 2;

  void generate(IndentingWriter out) {
    out.addAnnotatedBlock(
        'class $classname extends $protobufImportPrefix.ProtobufEnum {',
        '}\n', [
      NamedLocation(
          name: classname, fieldPathSegment: fieldPath, start: 'class '.length)
    ], () {
      // -----------------------------------------------------------------
      // Define enum types.
      for (var i = 0; i < _canonicalValues.length; i++) {
        var val = _canonicalValues[i];
        final name = dartNames[val.name];
        final conditionalValName = configurationDependent(
            'protobuf.omit_enum_names', quoted(val.name));
        out.printlnAnnotated(
            'static const $classname $name = '
            '$classname._(${val.number}, $conditionalValName);',
            [
              NamedLocation(
                  name: name,
                  fieldPathSegment: List.from(fieldPath)
                    ..addAll([_enumValueTag, _originalCanonicalIndices[i]]),
                  start: 'static const $classname '.length)
            ]);
      }
      if (_aliases.isNotEmpty) {
        out.println();
        for (var i = 0; i < _aliases.length; i++) {
          var alias = _aliases[i];
          final name = dartNames[alias.value.name];
          out.printlnAnnotated(
              'static const $classname $name ='
              ' ${dartNames[alias.canonicalValue.name]};',
              [
                NamedLocation(
                    name: name,
                    fieldPathSegment: List.from(fieldPath)
                      ..addAll([_enumValueTag, _originalAliasIndices[i]]),
                    start: 'static const $classname '.length)
              ]);
        }
      }
      out.println();

      out.println('static const $coreImportPrefix.List<$classname> values ='
          ' <$classname> [');
      for (var val in _canonicalValues) {
        final name = dartNames[val.name];
        out.println('  $name,');
      }
      out.println('];');
      out.println();

      out.println(
          'static final $coreImportPrefix.Map<$coreImportPrefix.int, $classname> _byValue ='
          ' $protobufImportPrefix.ProtobufEnum.initByValue(values);');
      out.println('static $classname? valueOf($coreImportPrefix.int value) =>'
          ' _byValue[value];');
      out.println();

      out.println(
          'const $classname._($coreImportPrefix.int v, $coreImportPrefix.String n) '
          ': super(v, n);');
    });
  }

  /// Writes a Dart constant containing the JSON for the EnumProtoDescriptor.
  void generateConstants(IndentingWriter out) {
    var name = getJsonConstant(fileGen);
    var json = _descriptor.writeToJsonMap();

    out.println('@$coreImportPrefix.Deprecated'
        '(\'Use ${toplevelParent.binaryDescriptorName} instead\')');
    out.print('const $name = ');
    writeJsonConst(out, json);
    out.println(';');
    out.println();
  }
}
