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

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

class IrAnnotationData {
  Map<ir.Class, String> _nativeClassNames = {};
  Set<ir.Member> _nativeMembers = {};
  Map<ir.Member, String> _nativeMemberNames = {};
  Map<ir.Member, List<String>> _createsAnnotations = {};
  Map<ir.Member, List<String>> _returnsAnnotations = {};

  Map<ir.Library, String> _jsInteropLibraryNames = {};
  Map<ir.Class, String> _jsInteropClassNames = {};
  Set<ir.Class> _anonymousJsInteropClasses = {};
  Map<ir.Member, String> _jsInteropMemberNames = {};

  Map<ir.Member, List<PragmaAnnotationData>> _memberPragmaAnnotations = {};

  // Returns the text from the `@Native(<text>)` annotation of [node], if any.
  String getNativeClassName(ir.Class node) => _nativeClassNames[node];

  // Returns `true` if [node] has a native body, as in `method() native;`.
  bool hasNativeBody(ir.Member node) => _nativeMembers.contains(node);

  // Returns the text from the `@JSName(<text>)` annotation of [node], if any.
  String getNativeMemberName(ir.Member node) => _nativeMemberNames[node];

  // Returns a list of the text from the `@Creates(<text>)` annotation of
  // [node].
  List<String> getCreatesAnnotations(ir.Member node) =>
      _createsAnnotations[node] ?? const [];

  // Returns a list of the text from the `@Returns(<text>)` annotation of
  // [node].
  List<String> getReturnsAnnotations(ir.Member node) =>
      _returnsAnnotations[node] ?? const [];

  // Returns the text from the `@JS(<text>)` annotation of [node], if any.
  String getJsInteropLibraryName(ir.Library node) =>
      _jsInteropLibraryNames[node];

  // Returns the text from the `@JS(<text>)` annotation of [node], if any.
  String getJsInteropClassName(ir.Class node) => _jsInteropClassNames[node];

  // Returns `true` if [node] is annotated with `@anonymous`.
  bool isAnonymousJsInteropClass(ir.Class node) =>
      _anonymousJsInteropClasses.contains(node);

  // Returns the text from the `@JS(<text>)` annotation of [node], if any.
  String getJsInteropMemberName(ir.Member node) => _jsInteropMemberNames[node];

  // Returns a list of the `@pragma('dart2js:<suffix>')` annotations on [node].
  List<PragmaAnnotationData> getMemberPragmaAnnotationData(ir.Member node) =>
      _memberPragmaAnnotations[node] ?? const [];

  void forEachNativeClass(void Function(ir.Class, String) f) {
    _nativeClassNames.forEach(f);
  }

  void forEachJsInteropLibrary(void Function(ir.Library, String) f) {
    _jsInteropLibraryNames.forEach(f);
  }

  void forEachJsInteropClass(
      void Function(ir.Class, String, {bool isAnonymous}) f) {
    _jsInteropClassNames.forEach((ir.Class node, String name) {
      f(node, name, isAnonymous: isAnonymousJsInteropClass(node));
    });
  }

  void forEachJsInteropMember(void Function(ir.Member, String) f) {
    _jsInteropLibraryNames.forEach((ir.Library library, _) {
      for (ir.Member member in library.members) {
        if (member.isExternal) {
          f(member, _jsInteropMemberNames[member] ?? member.name.name);
        }
      }
    });
    _jsInteropClassNames.forEach((ir.Class cls, _) {
      for (ir.Member member in cls.members) {
        if (member is ir.Field) continue;
        String name = _jsInteropMemberNames[member];
        if (member.isExternal) {
          name ??= member.name.name;
        }
        f(member, name);
      }
    });
  }

  void forEachNativeMethodData(
      void Function(ir.Member, String name, Iterable<String> createsAnnotations,
              Iterable<String> returnsAnnotations)
          f) {
    for (ir.Member node in _nativeMembers) {
      if (node is! ir.Field) {
        String name = _nativeMemberNames[node] ?? node.name.name;
        f(node, name, getCreatesAnnotations(node), getReturnsAnnotations(node));
      }
    }
  }

  void forEachNativeFieldData(
      void Function(ir.Member, String name, Iterable<String> createsAnnotations,
              Iterable<String> returnsAnnotations)
          f) {
    for (ir.Class cls in _nativeClassNames.keys) {
      for (ir.Field field in cls.fields) {
        if (field.isInstanceMember) {
          String name = _nativeMemberNames[field] ?? field.name.name;
          f(field, name, getCreatesAnnotations(field),
              getReturnsAnnotations(field));
        }
      }
    }
  }
}

IrAnnotationData processAnnotations(ir.Component component) {
  IrAnnotationData data = new IrAnnotationData();

  void processMember(ir.Member member) {
    List<PragmaAnnotationData> pragmaAnnotations;
    List<String> createsAnnotations;
    List<String> returnsAnnotations;
    for (ir.Expression annotation in member.annotations) {
      if (annotation is ir.ConstantExpression) {
        ir.Constant constant = annotation.constant;

        String jsName = _getJsInteropName(constant);
        if (jsName != null) {
          data._jsInteropMemberNames[member] = jsName;
        }

        bool isNativeMember = _isNativeMember(constant);
        if (isNativeMember) {
          data._nativeMembers.add(member);
        }

        String nativeName = _getNativeMemberName(constant);
        if (nativeName != null) {
          data._nativeMemberNames[member] = nativeName;
        }

        String creates = _getCreatesAnnotation(constant);
        if (creates != null) {
          if (createsAnnotations == null) {
            data._createsAnnotations[member] = createsAnnotations = [];
          }
          createsAnnotations.add(creates);
        }

        String returns = _getReturnsAnnotation(constant);
        if (returns != null) {
          if (returnsAnnotations == null) {
            data._returnsAnnotations[member] = returnsAnnotations = [];
          }
          returnsAnnotations.add(returns);
        }

        PragmaAnnotationData pragmaAnnotation = _getPragmaAnnotation(constant);
        if (pragmaAnnotation != null) {
          if (pragmaAnnotations == null) {
            data._memberPragmaAnnotations[member] = pragmaAnnotations = [];
          }
          pragmaAnnotations.add(pragmaAnnotation);
        }
      }
    }
  }

  for (ir.Library library in component.libraries) {
    for (ir.Expression annotation in library.annotations) {
      if (annotation is ir.ConstantExpression) {
        ir.Constant constant = annotation.constant;

        String jsName = _getJsInteropName(constant);
        if (jsName != null) {
          data._jsInteropLibraryNames[library] = jsName;
        }
      }
    }
    for (ir.Class cls in library.classes) {
      for (ir.Expression annotation in cls.annotations) {
        if (annotation is ir.ConstantExpression) {
          ir.Constant constant = annotation.constant;

          String nativeClassName = _getNativeClassName(constant);
          if (nativeClassName != null) {
            data._nativeClassNames[cls] = nativeClassName;
          }

          String jsName = _getJsInteropName(constant);
          if (jsName != null) {
            data._jsInteropClassNames[cls] = jsName;
          }

          bool isAnonymousJsInteropClass = _isAnonymousJsInterop(constant);
          if (isAnonymousJsInteropClass) {
            data._anonymousJsInteropClasses.add(cls);
          }
        }
      }
      for (ir.Member member in cls.members) {
        processMember(member);
      }
    }
    for (ir.Member member in library.members) {
      processMember(member);
    }
  }
  return data;
}

String _getNativeClassName(ir.Constant constant) {
  if (constant is ir.InstanceConstant) {
    // TODO(johnniwinther): Add an IrCommonElements for these queries; i.e.
    // `commonElements.isNativeAnnotationClass(constant.classNode)`.
    if (constant.classNode.name == 'Native' &&
        constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
      if (constant.fieldValues.length == 1) {
        ir.Constant fieldValue = constant.fieldValues.values.single;
        String name;
        if (fieldValue is ir.StringConstant) {
          name = fieldValue.value;
        }
        if (name != null) {
          return name;
        }
      }
    }
  }
  return null;
}

bool _isNativeMember(ir.Constant constant) {
  return constant is ir.InstanceConstant &&
      constant.classNode.name == 'ExternalName' &&
      constant.classNode.enclosingLibrary.importUri == Uris.dart__internal;
}

String _getNativeMemberName(ir.Constant constant) {
  if (constant is ir.InstanceConstant &&
      constant.classNode.name == 'JSName' &&
      constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
    assert(constant.fieldValues.length == 1);
    ir.Constant fieldValue = constant.fieldValues.values.single;
    if (fieldValue is ir.StringConstant) {
      return fieldValue.value;
    }
  }
  return null;
}

String _getCreatesAnnotation(ir.Constant constant) {
  if (constant is ir.InstanceConstant &&
      constant.classNode.name == 'Creates' &&
      constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
    assert(constant.fieldValues.length == 1);
    ir.Constant fieldValue = constant.fieldValues.values.single;
    if (fieldValue is ir.StringConstant) {
      return fieldValue.value;
    }
  }
  return null;
}

String _getReturnsAnnotation(ir.Constant constant) {
  if (constant is ir.InstanceConstant &&
      constant.classNode.name == 'Returns' &&
      constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
    assert(constant.fieldValues.length == 1);
    ir.Constant fieldValue = constant.fieldValues.values.single;
    if (fieldValue is ir.StringConstant) {
      return fieldValue.value;
    }
  }
  return null;
}

String _getJsInteropName(ir.Constant constant) {
  if (constant is ir.InstanceConstant &&
      constant.classNode.name == 'JS' &&
      constant.classNode.enclosingLibrary.importUri == Uris.package_js) {
    assert(constant.fieldValues.length == 1);
    ir.Constant fieldValue = constant.fieldValues.values.single;
    if (fieldValue is ir.NullConstant) {
      return '';
    } else if (fieldValue is ir.StringConstant) {
      return fieldValue.value;
    }
  }
  return null;
}

bool _isAnonymousJsInterop(ir.Constant constant) {
  return constant is ir.InstanceConstant &&
      constant.classNode.name == '_Anonymous' &&
      constant.classNode.enclosingLibrary.importUri == Uris.package_js;
}

class PragmaAnnotationData {
  // TODO(johnniwinther): Support non 'dart2js:' pragma names if necessary.
  final String suffix;

  // TODO(johnniwinther): Support options objects when necessary.
  final bool hasOptions;

  const PragmaAnnotationData(this.suffix, {this.hasOptions: false});

  String get name => 'dart2js:$suffix';

  @override
  String toString() => 'PragmaAnnotationData($name)';
}

PragmaAnnotationData _getPragmaAnnotation(ir.Constant constant) {
  if (constant is! ir.InstanceConstant) return null;
  ir.InstanceConstant value = constant;
  ir.Class cls = value.classNode;
  Uri uri = cls.enclosingLibrary.importUri;
  if (uri == Uris.package_meta_dart2js) {
    if (cls.name == '_NoInline') {
      return const PragmaAnnotationData('noInline');
    } else if (cls.name == '_TryInline') {
      return const PragmaAnnotationData('tryInline');
    }
  } else if (uri == Uris.dart_core && cls.name == 'pragma') {
    ir.Constant nameValue;
    ir.Constant optionsValue;
    value.fieldValues.forEach((ir.Reference reference, ir.Constant fieldValue) {
      ir.Field field = reference.asField;
      if (field.name.name == 'name') {
        nameValue = fieldValue;
      } else if (field.name.name == 'options') {
        optionsValue = fieldValue;
      }
    });
    if (nameValue is! ir.StringConstant) return null;
    ir.StringConstant stringValue = nameValue;
    String name = stringValue.value;
    String prefix = 'dart2js:';
    if (!name.startsWith(prefix)) return null;
    String suffix = name.substring(prefix.length);
    return new PragmaAnnotationData(suffix,
        hasOptions: optionsValue is! ir.NullConstant);
  }
  return null;
}

List<PragmaAnnotationData> computePragmaAnnotationDataFromIr(ir.Member member) {
  List<PragmaAnnotationData> annotations = [];
  for (ir.Expression metadata in member.annotations) {
    if (metadata is! ir.ConstantExpression) continue;
    ir.ConstantExpression constantExpression = metadata;
    ir.Constant constant = constantExpression.constant;
    PragmaAnnotationData data = _getPragmaAnnotation(constant);
    if (data != null) {
      annotations.add(data);
    }
  }
  return annotations;
}
