// 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'; //# 01: ok

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(); //# 01: continued
}
