// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.8

import 'package:html/dom.dart' as dom;

import '../common_util.dart';
import '../queries/index.dart';
import 'ast.dart';

dom.Element hr() => dom.Element.tag('hr');
dom.Element h1(dom.Node content) => dom.Element.tag('h1')..append(content);
dom.Element h2(dom.Node content) => dom.Element.tag('h2')..append(content);
dom.Element h3(dom.Node content) => dom.Element.tag('h3')..append(content);
dom.Element div(dom.Node content) => dom.Element.tag('div')..append(content);
dom.Element divChildren(Iterable<dom.Node> content) =>
    dom.Element.tag('div')..nodes.addAll(content);
dom.Element ul(Iterable<dom.Node> content) =>
    dom.Element.tag('ul')..nodes.addAll(content);
dom.Element li(dom.Node content) => dom.Element.tag('li')..append(content);
dom.Element liChildren(Iterable<dom.Node> content) =>
    dom.Element.tag('li')..nodes.addAll(content);
dom.Element span(dom.Node content) => dom.Element.tag('span')..append(content);
dom.Element spanChildren(Iterable<dom.Node> content) =>
    dom.Element.tag('span')..nodes.addAll(content);
dom.Node text(String content) => dom.Text(content);

/// A renderer into HTML, supporting any level of nested nodes.
class HtmlRenderer extends Renderer {
  // ignore: prefer_interpolation_to_compose_strings
  static final String _css = '''
html {
  font-size: 100%;
}

body {
  font-family: Noto, Roboto, Arial, Helvetica, sans-serif;
  font-size: 1.0rem;
  background-color: white;
  color: black;
}

ul {
  margin-left: 0;
  padding-left: 1rem;
}

ul ul {
  padding-left: 2rem;
  border-left: 3px solid #f77;
  background-color: #f1f1f1;
  list-style-type: square;
  list-style-position: outside;
}

ul ul ul {
  padding-left: 3rem;
}

body>ul>li div:last-child {
  margin-bottom: 0.8rem;
}

/* Make deeply nested items smaller */
body>ul>li li {
  font-size: 0.8rem;
}
''' +
      Color.values.map((c) => '''
.${c.className} {
  color: ${c.colorName};
  font-weight: bold;
}
''').join('\n');

  @override
  void render(StringSink output, Iterable<Query> queries) {
    final document = dom.Document.html('''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
</html>
''');
    document.head.append(document.createElement('style')..innerHtml = _css);
    final body = document.body;
    bool first = true;
    for (final query in queries) {
      if (!first) {
        body.append(hr());
      }
      first = false;
      body
        ..append(h2(text(query.name)))
        ..append(div(text(query.getDescription())));
      final result = query.distill().export();
      body.append(ul([
        for (final node in result) liChildren(_renderNode(node, indent: 0))
      ]));
    }
    output.writeln(document.outerHtml);
  }

  Iterable<dom.Node> _renderNode(AnyNode node, {int indent = 0}) => [
        if (node.title != null) _renderTitle(node.title),
        if (indent == 0)
          for (final child in node.children ?? [])
            divChildren(_renderNode(child, indent: indent + 1))
        else if ((node.children ?? []).isNotEmpty)
          ul([
            for (final child in node.children)
              ..._renderNode(child, indent: indent + 1).map(li)
          ])
      ];

  dom.Node _renderTitle(Title title) {
    if (title is StringPiece) {
      // Dart analysis failed to narrow the type here..
      // ignore: avoid_as
      return _renderStringPiece(title as StringPiece);
    } else if (title is UniqueSymbolSizeRecord) {
      return spanChildren([
        _renderStringPiece(title.name),
        text(': ${formatSize(title.tally.size)} (${title.tally.size}), '
            '${title.tally.count} total symbols'),
        div(spanChildren([
          text('In categories: '),
          ...title.categories.map(_renderStringPiece).expand((e) => [
                e,
                text(' '),
              ]),
        ])),
        if (title.rustCrates.isNotEmpty)
          div(spanChildren([
            text('In rust crates: '),
            ...title.rustCrates.map(_renderStringPiece).expand((e) => [
                  e,
                  text(' '),
                ]),
          ])),
      ]);
    } else if (title is SizeRecord) {
      return spanChildren([
        _renderStringPiece(title.name),
        text(': ${formatSize(title.tally.size)} (${title.tally.size}), '
            '${title.tally.count} total symbols')
      ]);
    } else {
      throw Exception('Unsupported $title');
    }
  }

  dom.Node _renderStringPiece(StringPiece piece) {
    if (piece is AddColor) {
      return _colorize(
          spanChildren(piece.details.map(_renderStringPiece)), piece.color);
    } else if (piece is StyledString) {
      return spanChildren(piece.details.map(_renderStringPiece));
    } else if (piece is Plain) {
      return text(piece.text);
    } else {
      throw Exception('Unsupported $piece');
    }
  }

  dom.Element _colorize(dom.Element str, Color color) =>
      str..classes.add(color.className);
}

extension _css on Color {
  String get className => 'codesize-color-$colorName';

  // All codepaths in the switch will always return.
  String get colorName {
    switch (this) {
      case Color.gray:
        return 'gray';
      case Color.green:
        return 'green';
      case Color.white:
        // Since terminal background is black, but webpage is white,
        // we'll swap around the black and white color in HTML.
        return 'black';
    }
    throw Exception('Unreachable');
  }
}
