// 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();
}
