// Copyright (c) 2015, 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 '../js_ast/js_ast.dart' as JS show TypeRef, ClosureTypePrinter;

/// Set of closure annotations that can be [toString]ed to a single JsDoc comment.
/// See https://developers.google.com/closure/compiler/docs/js-for-compiler
///
/// TODO(ochafik): Support inclusion of 'normal' comments (including @param comments).
class ClosureAnnotation {
  final String comment;
  final bool isConst;
  final bool isConstructor;
  final bool isFinal;
  final bool isNoCollapse;
  final bool isNoSideEffects;
  final bool isOverride;
  final bool isPrivate;
  final bool isProtected;
  final bool isStruct;
  final bool isTypedef;
  final JS.TypeRef lendsToType;
  final JS.TypeRef returnType;
  final JS.TypeRef superType;
  final JS.TypeRef thisType;
  final JS.TypeRef throwsType;
  final JS.TypeRef type;
  final List<JS.TypeRef> interfaces;
  final List<String> templates;
  final Map<String, JS.TypeRef> paramTypes;

  ClosureAnnotation(
      {this.comment,
      this.interfaces = const [],
      this.isConst = false,
      this.isConstructor = false,
      this.isFinal = false,
      this.isNoCollapse = false,
      this.isNoSideEffects = false,
      this.isOverride = false,
      this.isPrivate = false,
      this.isProtected = false,
      this.isStruct = false,
      this.isTypedef = false,
      this.lendsToType,
      this.paramTypes = const {},
      this.returnType,
      this.superType,
      this.templates = const [],
      this.thisType,
      this.throwsType,
      this.type});

  @override
  int get hashCode => _cachedString.hashCode;

  @override
  bool operator ==(other) =>
      other is ClosureAnnotation && _cachedString == other._cachedString;

  @override
  String toString([String indent = '']) =>
      _cachedString.replaceAll('\n', '\n$indent');

  String _print(JS.TypeRef t) => (JS.ClosureTypePrinter()..visit(t)).toString();

  String __cachedString;
  String get _cachedString {
    if (__cachedString == null) {
      bool isNonWildcard(JS.TypeRef t) => t != null && !t.isAny && !t.isUnknown;

      var lines = <String>[];
      if (comment != null) lines.addAll(comment.split('\n'));
      if (templates != null && templates.isNotEmpty) {
        lines.add('@template ${templates.join(', ')}');
      }
      if (thisType != null) lines.add('@this {${_print(thisType)}}');
      if (isOverride) lines.add('@override');
      if (isNoSideEffects) lines.add('@nosideeffects');
      if (isNoCollapse) lines.add('@nocollapse');
      if (lendsToType != null) lines.add('@lends {${_print(lendsToType)}}');

      {
        var typeHolders = <String>[];
        if (isPrivate) typeHolders.add('@private');
        if (isProtected) typeHolders.add('@protected');
        if (isFinal) typeHolders.add('@final');
        if (isConst) typeHolders.add('@const');
        if (isTypedef) typeHolders.add('@typedef');
        if (isNonWildcard(type)) {
          if (typeHolders.isEmpty) typeHolders.add('@type');
          typeHolders.add('{${_print(type)}}');
        }
        if (!typeHolders.isEmpty) lines.add(typeHolders.join(' '));
      }

      {
        List constructorLine = [];
        if (isConstructor) constructorLine.add('@constructor');
        if (isStruct) constructorLine.add('@struct');
        if (isNonWildcard(superType)) {
          constructorLine.add('@extends {${_print(superType)}}');
        }

        if (constructorLine.isNotEmpty) lines.add(constructorLine.join(' '));
      }

      if (interfaces != null) {
        for (var interface in interfaces) {
          if (isNonWildcard(interface))
            lines.add('@implements {${_print(interface)}}');
        }
      }

      if (paramTypes != null) {
        paramTypes.forEach((String paramName, JS.TypeRef paramType) {
          // Must output params even with wildcard type.
          lines.add('@param {${_print(paramType)}} $paramName');
        });
      }
      if (isNonWildcard(returnType))
        lines.add('@return {${_print(returnType)}}');
      if (isNonWildcard(throwsType))
        lines.add('@throws {${_print(throwsType)}}');

      if (lines.length == 0) return '';
      if (lines.length == 1) return '/** ${lines.single} */';
      __cachedString = '/**\n' + lines.map((l) => ' * $l').join('\n') + '\n */';
    }
    return __cachedString;
  }
}
