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

/**
 * The docgen tool takes in a library as input and produces documentation
 * for the library as well as all libraries it imports and uses. The tool can
 * be run by passing in the path to a .dart file like this:
 *
 *   ./dart docgen.dart path/to/file.dart
 *
 * This outputs information about all classes, variables, functions, and
 * methods defined in the library and its imported libraries.
 */
library docgen;

// TODO(tmandel): Use 'package:' references for imports with relative paths.
import 'dart:io';
import 'dart:json';
import 'dart:async';
import '../lib/dart2yaml.dart';
import '../lib/src/dart2js_mirrors.dart';
import 'package:markdown/markdown.dart' as markdown;
import '../../args/lib/args.dart';
import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';

/**
 * Entry function to create YAML documentation from Dart files.
 */
void main() {
  // TODO(tmandel): Use args library once flags are clear.
  Options opts = new Options();
  Docgen docgen = new Docgen();
  
  if (opts.arguments.length > 0) {
    List<Path> libraries = [new Path(opts.arguments[0])];
    Path sdkDirectory = new Path("../../../sdk/");
    var workingMirrors = analyze(libraries, sdkDirectory, 
        options: ['--preserve-comments', '--categories=Client,Server']);
    workingMirrors.then( (MirrorSystem mirrorSystem) {
      var mirrors = mirrorSystem.libraries.values;
      if (mirrors.isEmpty) {
        print("no LibraryMirrors");
      } else {
        docgen.libraries = mirrors;
        docgen.documentLibraries();
      }
    });
  }
}

/**
 * This class documents a list of libraries.
 */
class Docgen {

  /// Libraries to be documented.
  List<LibraryMirror> _libraries;
  
  /// Saves list of libraries for Docgen object.
  void set libraries(value) => _libraries = value;
  
  /// Current library being documented to be used for comment links.
  LibraryMirror _currentLibrary;
  
  /// Current class being documented to be used for comment links.
  ClassMirror _currentClass;
  
  /// Current member being documented to be used for comment links.
  MemberMirror _currentMember;
  
  /// Should the output file type be JSON?
  // TODO(tmandel): Add flag to allow for output to JSON.
  bool outputToJson = false;
  
  /// Resolves reference links
  markdown.Resolver linkResolver;
  
  /**
   * Docgen constructor initializes the link resolver for markdown parsing.
   */
  Docgen() {
    this.linkResolver = (name) => 
        fixReference(name, _currentLibrary, _currentClass, _currentMember);
  }
  
  /**
   * Creates documentation for filtered libraries.
   */
  void documentLibraries() {
    //TODO(tmandel): Filter libraries and determine output type using flags.
    _libraries.forEach((library) {
      _currentLibrary = library;
      var result = new Library(library.qualifiedName, _getComment(library),
          _getVariables(library.variables), _getMethods(library.functions),
          _getClasses(library.classes));
      if (outputToJson) {
        _writeToFile(stringify(result.toMap()), "${result.name}.json");
      } else {
        _writeToFile(getYamlString(result.toMap()), "${result.name}.yaml");
      }
    });
   }
  
  /**
   * Returns any documentation comments associated with a mirror with
   * simple markdown converted to html.
   */
  String _getComment(DeclarationMirror mirror) {
    String commentText;
    mirror.metadata.forEach((metadata) {
      if (metadata is CommentInstanceMirror) {
        CommentInstanceMirror comment = metadata;
        if (comment.isDocComment) {
          if (commentText == null) {
            commentText = comment.trimmedText;
          } else {
            commentText = "$commentText ${comment.trimmedText}";
          }
        } 
      }
    });
    return commentText == null ? "" : 
      markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver);
  }

  /**
   * Converts all [_] references in comments to <code>_</code>.
   */
  // TODO(tmandel): Create proper links for [_] style markdown based
  // on scope once layout of viewer is finished.
  markdown.Node fixReference(String name, LibraryMirror currentLibrary, 
      ClassMirror currentClass, MemberMirror currentMember) {
    return new markdown.Element.text('code', name);
  }
  
  /**
   * Returns a map of [Variable] objects constructed from inputted mirrors.
   */
  Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap) {
    var data = {};
    mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
      _currentMember = mirror;
      data[mirrorName] = new Variable(mirrorName, mirror.isFinal,
          mirror.isStatic, mirror.type.toString(), _getComment(mirror));
    });
    return data;
  }
  
  /**
   * Returns a map of [Method] objects constructed from inputted mirrors.
   */
  Map<String, Method> _getMethods(Map<String, MethodMirror> mirrorMap) {
    var data = {};
    mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
      _currentMember = mirror;
      data[mirrorName] = new Method(mirrorName, mirror.isSetter,
          mirror.isGetter, mirror.isConstructor, mirror.isOperator, 
          mirror.isStatic, mirror.returnType.toString(), _getComment(mirror),
          _getParameters(mirror.parameters));
    });
    return data;
  } 
  
  /**
   * Returns a map of [Class] objects constructed from inputted mirrors.
   */
  Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap) {
    var data = {};
    mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
      _currentClass = mirror;
      var superclass;
      if (mirror.superclass != null) {
        superclass = mirror.superclass.qualifiedName;
      }
      var interfaces = 
          mirror.superinterfaces.map((interface) => interface.qualifiedName);
      data[mirrorName] = new Class(mirrorName, superclass, mirror.isAbstract,
          mirror.isTypedef, _getComment(mirror), interfaces,
          _getVariables(mirror.variables), _getMethods(mirror.methods));
    });
    return data;
  }
  
  /**
   * Returns a map of [Parameter] objects constructed from inputted mirrors.
   */
  Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) {
    var data = {};
    mirrorList.forEach((ParameterMirror mirror) {
      _currentMember = mirror;
      data[mirror.simpleName] = new Parameter(mirror.simpleName, 
          mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, 
          mirror.type.toString(), mirror.defaultValue);
    });
    return data;
  }
}

/**
 * Transforms the map by calling toMap on each value in it.
 */
Map recurseMap(Map inputMap) {
  var outputMap = {};
  inputMap.forEach((key, value) {
    outputMap[key] = value.toMap();
  });
  return outputMap;
}

/**
 * A class containing contents of a Dart library.
 */
class Library {
  
  /// Documentation comment with converted markdown.
  String comment;
  
  /// Top-level variables in the library.
  Map<String, Variable> variables;
  
  /// Top-level functions in the library.
  Map<String, Method> functions;
  
  /// Classes defined within the library
  Map<String, Class> classes;
  
  String name;
  
  Library(this.name, this.comment, this.variables, 
      this.functions, this.classes);
  
  /// Generates a map describing the [Library] object.
  Map toMap() {
    var libraryMap = {};
    libraryMap["name"] = name;
    libraryMap["comment"] = comment;
    libraryMap["variables"] = recurseMap(variables);
    libraryMap["functions"] = recurseMap(functions);
    libraryMap["classes"] = recurseMap(classes);
    return libraryMap;
  }
}

/**
 * A class containing contents of a Dart class.
 */
// TODO(tmandel): Figure out how to do typedefs (what is needed)
class Class {
  
  /// Documentation comment with converted markdown.
  String comment;
  
  /// List of the names of interfaces that this class implements.
  List<String> interfaces;
  
  /// Top-level variables in the class.
  Map<String, Variable> variables;
  
  /// Methods in the class.
  Map<String, Method> methods;
  
  String name;
  String superclass;
  bool isAbstract;
  bool isTypedef;
 
  Class(this.name, this.superclass, this.isAbstract, this.isTypedef,
      this.comment, this.interfaces, this.variables, this.methods); 
  
  /// Generates a map describing the [Class] object.
  Map toMap() {
    var classMap = {};
    classMap["name"] = name;
    classMap["comment"] = comment;
    classMap["superclass"] = superclass;
    classMap["abstract"] = isAbstract.toString();
    classMap["typedef"] = isTypedef.toString();
    classMap["implements"] = new List.from(interfaces);
    classMap["variables"] = recurseMap(variables);
    classMap["methods"] = recurseMap(methods);
    return classMap;
  }
}

/**
 * A class containing properties of a Dart variable.
 */
class Variable {
  
  /// Documentation comment with converted markdown.
  String comment;
  
  String name;
  bool isFinal;
  bool isStatic;
  String type;
  
  Variable(this.name, this.isFinal, this.isStatic, this.type, this.comment);
  
  /// Generates a map describing the [Variable] object.
  Map toMap() {
    var variableMap = {};
    variableMap["name"] = name;
    variableMap["comment"] = comment;
    variableMap["final"] = isFinal.toString();
    variableMap["static"] = isStatic.toString();
    variableMap["type"] = type;
    return variableMap;
  }
}

/**
 * A class containing properties of a Dart method.
 */
class Method {
  
  /// Documentation comment with converted markdown.
  String comment;
  
  /// Parameters for this method.
  Map<String, Parameter> parameters;
  
  String name;
  bool isSetter;
  bool isGetter;
  bool isConstructor;
  bool isOperator;
  bool isStatic;
  String returnType;
  
  Method(this.name, this.isSetter, this.isGetter, this.isConstructor,
      this.isOperator, this.isStatic, this.returnType, this.comment,
      this.parameters);
  
  /// Generates a map describing the [Method] object.
  Map toMap() {
    var methodMap = {};
    methodMap["name"] = name;
    methodMap["comment"] = comment;
    methodMap["type"] = isSetter ? "setter" : isGetter ? "getter" :
      isOperator ? "operator" : isConstructor ? "constructor" : "method";
    methodMap["static"] = isStatic.toString();
    methodMap["return"] = returnType;
    methodMap["parameters"] = recurseMap(parameters);
    return methodMap;
  }  
}

/**
 * A class containing properties of a Dart method/function parameter.
 */
class Parameter {
  
  String name;
  bool isOptional;
  bool isNamed;
  bool hasDefaultValue;
  String type;
  String defaultValue;
  
  Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue,
      this.type, this.defaultValue);
  
  /// Generates a map describing the [Parameter] object.
  Map toMap() {
    var parameterMap = {};
    parameterMap["name"] = name;
    parameterMap["optional"] = isOptional.toString();
    parameterMap["named"] = isNamed.toString();
    parameterMap["default"] = hasDefaultValue.toString();
    parameterMap["type"] = type;
    parameterMap["value"] = defaultValue;
    return parameterMap;
  } 
}

/**
 * Writes text to a file in the 'docs' directory.
 */
void _writeToFile(String text, String filename) {
  Directory dir = new Directory('docs');
  if (!dir.existsSync()) {
    dir.createSync();
  }
  File file = new File('docs/$filename');
  if (!file.exists()) {
    file.createSync();
  }
  file.openSync();
  file.writeAsString(text);
}