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

// Usage: Add the following to your .gclient file (found in the parent
// of the "dart" in a gclient checkout of the Dart repositor).
//
// hooks = [
//   {
//     "pattern": ".",
//     "action": [
//       "dart/sdk/bin/dart",
//       "dart/sdk/lib/_internal/compiler/samples/darttags/darttags.dart",
//       "dart/TAGS"
//     ],
//   },
// ]
//
// Modify .emacs to contain:
//
//      (setq tags-table-list
//           '("DART_LOCATION/dart"))
//
// Where DART_LOCATION is the gclient directory where you found .gclient.

import 'dart:io';

// TODO(ahe): Should be dart:mirrors.
import '../../implementation/mirrors/mirrors.dart';

import '../../../libraries.dart'
    show LIBRARIES, LibraryInfo;

import '../../implementation/mirrors/dart2js_mirror.dart'
    show analyze, BackDoor;

import '../../implementation/filenames.dart';
import '../../implementation/source_file.dart';
import '../../implementation/source_file_provider.dart';
import '../../implementation/util/uri_extras.dart';

const DART2JS = '../../implementation/dart2js.dart';
const DART2JS_MIRROR = '../../implementation/mirrors/dart2js_mirror.dart';
const SDK_ROOT = '../../../../../';

bool isPublicDart2jsLibrary(String name) {
  return !name.startsWith('_') && LIBRARIES[name].isDart2jsLibrary;
}

var handler;
RandomAccessFile output;
Uri outputUri;

main(List<String> arguments) {
  handler = new FormattingDiagnosticHandler()
      ..throwOnError = true;

  outputUri =
      handler.provider.cwd.resolve(nativeToUriPath(arguments.first));
  output = new File(arguments.first).openSync(mode: FileMode.WRITE);

  Uri myLocation =
      handler.provider.cwd.resolveUri(Platform.script);

  // Get the names of public dart2js libraries.
  Iterable<String> names = LIBRARIES.keys.where(isPublicDart2jsLibrary);

  // Prepend "dart:" to the names.
  List<Uri> uris = names.map((String name) => Uri.parse('dart:$name')).toList();

  // Append dart2js itself.
  uris.add(myLocation.resolve(DART2JS));
  uris.add(myLocation.resolve(DART2JS_MIRROR));

  analyze(uris, myLocation.resolve(SDK_ROOT), null, handler.provider, handler)
      .then(processMirrors);
}

processMirrors(MirrorSystem mirrors) {
  mirrors.libraries.forEach((_, LibraryMirror library) {
    BackDoor.compilationUnitsOf(library).forEach(emitTagsForCompilationUnit);
  });

  output.closeSync();
}

/**
 * From http://en.wikipedia.org/wiki/Ctags#Etags_2
 *
 * A section starts with a two line header, one line containing a
 * single <\x0c> character, followed by a line which consists of:
 *
 * {src_file},{size_of_tag_definition_data_in_bytes}
 *
 * The header is followed by tag definitions, one definition per line,
 * with the format:
 *
 * {tag_definition_text}<\x7f>{tagname}<\x01>{line_number},{byte_offset}
 */
emitTagsForCompilationUnit(compilationUnit) {
  // Certain variables in this method do not follow Dart naming
  // conventions.  This is because the format as written on Wikipedia
  // looks very similar to Dart string interpolation that the author
  // felt it would make sense to keep the names.
  Uri uri = compilationUnit.uri;
  var buffer = new StringBuffer();
  SourceFile file = handler.provider.sourceFiles['$uri'];

  compilationUnit.members.forEach((DeclarationMirror mirror) {
    var tagname = mirror.simpleName;
    var byte_offset = mirror.getBeginToken().charOffset;
    var line_number = file.getLine(byte_offset) + 1;

    var lineStart = file.lineStarts[line_number - 1];
    // TODO(ahe): Most often an empty string.  Try to see if we can
    // get the position of the name token instead.
    var tag_definition_text = file.slowText().substring(lineStart, byte_offset);

    // One definition.
    buffer.write('${tag_definition_text}\x7f${tagname}'
                 '\x01${line_number},${byte_offset}\n');
  });

  var tag_definition_data = '$buffer';
  var src_file = relativize(outputUri, uri, false);
  var size_of_tag_definition_data_in_bytes = tag_definition_data.length;

  // The header.
  output.writeStringSync(
      '\x0c\n${src_file},${size_of_tag_definition_data_in_bytes}\n');
  output.writeStringSync(tag_definition_data);
}
