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

/// This library provides a single function called injectLogs which when called
/// will request a logs json file and build a small widget out of them which
/// groups the logs by level.
library polymer.build.log_injector;

import 'dart:async';
import 'dart:convert';
import 'dart:html';

import 'package:path/path.dart' as path;

class LogInjector {
  Element selectedMenu;
  Element selectedContent;

  // Gets the logs from a url and inject them into the dom.
  Future injectLogsFromUrl(String url) =>
      HttpRequest.getString(url).then((data) => injectLogs(data));

  // Builds the html for the logs element given some logs, and injects that
  // into the dom. Currently, we do not  use Polymer just to ensure that the
  // page works regardless of the state of the app. Ideally, we could have
  // multiple scripts running independently so we could ensure that this would
  // always be running.
  injectLogs(String data) {
    // Group all logs by level.
    var logsByLevel = {
    };
    JSON.decode(data).forEach((log) {
      logsByLevel.putIfAbsent(log['level'], () => []);
      logsByLevel[log['level']].add(log);
    });
    if (logsByLevel.isEmpty) return;

    // Build the wrapper, menu, and content divs.

    var menuWrapper = new DivElement()
      ..classes.add('menu');
    var contentWrapper = new DivElement()
      ..classes.add('content');
    var wrapperDiv = new DivElement()
      ..classes.add('build-logs')
      ..append(menuWrapper)
      ..append(contentWrapper);

    // For each log level, add a menu item, content section, and all the logs.
    logsByLevel.forEach((level, logs) {
      var levelClassName = level.toLowerCase();

      // Add the menu item and content item.
      var menuItem = new Element.html(
          '<div class="$levelClassName">'
          '$level <span class="num">(${logs.length})</span>'
          '</div>');
      menuWrapper.append(menuItem);
      var contentItem = new DivElement()
        ..classes.add(levelClassName);
      contentWrapper.append(contentItem);

      // Set up the click handlers.
      menuItem.onClick.listen((_) {
        if (selectedMenu == menuItem) {
          selectedMenu = null;
          selectedContent = null;
        } else {
          if (selectedMenu != null) {
            selectedMenu.classes.remove('active');
            selectedContent.classes.remove('active');
          }

          selectedMenu = menuItem;
          selectedContent = contentItem;
        }

        menuItem.classes.toggle('active');
        contentItem.classes.toggle('active');
      });

      // Add the logs to the content item.
      for (var log in logs) {
        var logHtml = new StringBuffer();
        logHtml.write('<div class="log">');
        var message = log['message'].replaceAllMapped(_urlRegex,
            (m) => '<a href="${m.group(0)}" target="blank">${m.group(0)}</a>');
        logHtml.write('<div class="message $levelClassName">$message</div>');
        var assetId = log['assetId'];
        var span = log['span'];
        bool hasLocation = assetId != null || span != null;
        if (hasLocation) logHtml.write('<div class="location">');
        if (assetId != null) {
          logHtml.write(
              '  <span class="package">${assetId['package']}</span>:');
          if (span == null) {
            logHtml.write('  <span class="location">${assetId['path']}</span>');
          }
        }
        if (span != null) {
          logHtml.write(
              '  <span class="location">${span['location']}</span></div>'
              '  <span class="text">${span['text']}</span>''</div>');
        } else if (hasLocation) {
          logHtml.write('</div>');
        }
        logHtml.write('</div>');

        var logElement = new Element.html(logHtml.toString(),
            validator: new NodeValidatorBuilder.common()
              ..allowNavigation(new _OpenUriPolicy()));
        contentItem.append(logElement);
        var messageElement = logElement.querySelector('.message');
        messageElement.onClick.listen((e) {
          if (e.target == messageElement) {
            messageElement.classes.toggle('expanded');
          }
        });
      };
    });

    document.body.append(wrapperDiv);
  }

}

final _urlRegex = new RegExp('http://[^ ]*');
class _OpenUriPolicy implements UriPolicy {
  bool allowsUri(String uri) => true;
}
