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

/// Prints all information about all mirrors. This tests that it is possible to
/// enumerate all reflective information without crashing.

// Note: Adding imports below is fine for regression tests. For example,
// 'crash_library_metadata.dart' is imported to ensure the compiler doesn't
// crash.

// TODO(ahe): This test should be extended until we are sure all data is
// printed.

library test.mirror_printer_test;

@MirrorsUsed(targets: '*')
import 'dart:mirrors';

import 'crash_library_metadata.dart'; // This would crash dart2js.

// Importing dart:html to make things interesting.
import 'dart:html';

class MirrorPrinter {
  final StringBuffer buffer;
  final TypeMirror dynamicType = currentMirrorSystem().dynamicType;

  int indentationLevel = 0;

  MirrorPrinter(this.buffer);

  void w(object) {
    buffer.write(object);
  }

  n(Symbol symbol) => MirrorSystem.getName(symbol);

  void indented(action) {
    indentationLevel++;
    action();
    indentationLevel--;
  }

  get indent {
    for (int i = 0; i < indentationLevel; i++) {
      w('  ');
    }
  }

  String stringifyInstance(InstanceMirror mirror) {
    var reflectee = mirror.reflectee;
    if (reflectee is String) return '"${reflectee}"';
    if (reflectee is Null || reflectee is bool || reflectee is num ||
        reflectee is List || reflectee is Map) {
      return '$reflectee';
    }
    StringBuffer buffer = new StringBuffer();
    Map<Symbol, DeclarationMirror> declarations = mirror.type.declarations;
    buffer
        ..write(n(mirror.type.simpleName))
        ..write('(');
    bool first = true;
    declarations.forEach((Symbol name, DeclarationMirror declaration) {
      if (declaration is! VariableMirror) return;
      VariableMirror variable = declaration;
      if (variable.isStatic) return;
      // TODO(ahe): Include superclasses.
      if (first) {
        first = false;
      } else {
        buffer.write(', ');
      }
      buffer
          ..write(n(name))
          ..write(': ')
          ..write(stringifyInstance(mirror.getField(name)));
    });
    buffer.write(')');
    return buffer.toString();
  }

  String stringifyMetadata(InstanceMirror mirror) {
    return '@${stringifyInstance(mirror)}';
  }

  bool writeType(TypeMirror mirror) {
    if (mirror == null || mirror == dynamicType) return false;
    w('${n(mirror.simpleName)} ');
    return true;
  }

  writeVariable(VariableMirror mirror) {
    bool needsVar = true;
    if (mirror.isStatic) w('static ');
    // TODO(ahe): What about const?
    if (mirror.isFinal) {
      w('final ');
      needsVar = false;
    }

    if (writeType(mirror.type)) needsVar = false;

    if (needsVar) {
      w('var ');
    }
    w('${n(mirror.simpleName)};');
  }

  writeMethod(MethodMirror mirror) {
    writeType(mirror.returnType);
    if (mirror.isOperator) {
      w('operator ');
    }
    if (mirror.isGetter) {
      w('get ');
    }
    if (mirror.isSetter) {
      w('set ');
    }
    w('${n(mirror.simpleName)}');
    if (!mirror.isGetter) {
      w('()');
    }
    w(';');
  }

  writeClass(ClassMirror mirror) {
    // TODO(ahe): Write 'abstract' if [mirror] is abstract.
    w('class ${n(mirror.simpleName)}');
    // TODO(ahe): Write superclass and interfaces.
    w(' {');
    bool first = true;
    indented(() {
      for (DeclarationMirror declaration in mirror.declarations.values) {
        if (first) {
          first = false;
        } else {
          w('\n');
        }
        writeDeclaration(declaration);
      }
    });
    w('\n}\n');
  }

  writeDeclaration(DeclarationMirror declaration) {
    w('\n');
    var metadata = declaration.metadata;
    if (!metadata.isEmpty) {
      indent;
      buffer.writeAll(metadata.map(stringifyMetadata), ' ');
      w('\n');
    }
    indent;
    if (declaration is ClassMirror) {
      writeClass(declaration);
    } else if (declaration is VariableMirror) {
      writeVariable(declaration);
    } else if (declaration is MethodMirror) {
      writeMethod(declaration);
    } else {
      // TODO(ahe): Test other subclasses of DeclarationMirror.
      w('$declaration');
    }
  }

  writeLibrary(LibraryMirror library) {
    w('library ${n(library.simpleName)};\n\n');
    library.declarations.values
        .where((d)=> d is! TypeMirror)
        .forEach(writeDeclaration);
    w('\n');
  }

  static StringBuffer stringify(Map<Uri, LibraryMirror> libraries) {
    StringBuffer buffer = new StringBuffer();
    libraries.values.forEach(new MirrorPrinter(buffer).writeLibrary);
    return buffer;
  }
}

main() {
  print(MirrorPrinter.stringify(currentMirrorSystem().libraries));
  // Clear the nodes to avoid confusing the fine test framework (by "fine" I
  // mean something else) -- ahe.
  document.body.nodes.clear();
}
