// Copyright (c) 2012, 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.

library compiler;

import 'dart:async';
import 'dart:collection' show SplayTreeMap;

import 'package:csslib/visitor.dart' show StyleSheet, treeToDebugString;
import 'package:html5lib/dom.dart';
import 'package:html5lib/parser.dart';

import 'analyzer.dart';
import 'css_analyzer.dart' show analyzeCss, findUrlsImported,
       findImportsInStyleSheet, parseCss;
import 'css_emitters.dart' show rewriteCssUris,
       emitComponentStyleSheet, emitOriginalCss, emitStyleSheet;
import 'file_system.dart';
import 'files.dart';
import 'info.dart';
import 'messages.dart';
import 'compiler_options.dart';
import 'utils.dart';

/**
 * Parses an HTML file [contents] and returns a DOM-like tree.
 * Note that [contents] will be a [String] if coming from a browser-based
 * [FileSystem], or it will be a [List<int>] if running on the command line.
 *
 * Adds emitted error/warning to [messages], if [messages] is supplied.
 */
Document parseHtml(contents, String sourcePath, Messages messages,
    bool checkDocType) {
  var parser = new HtmlParser(contents, generateSpans: true,
      sourceUrl: sourcePath);
  var document = parser.parse();

  // Note: errors aren't fatal in HTML (unless strict mode is on).
  // So just print them as warnings.
  for (var e in parser.errors) {
    if (checkDocType || e.errorCode != 'expected-doctype-but-got-start-tag') {
      messages.warning(e.message, e.span);
    }
  }
  return document;
}

/** Compiles an application written with Dart web components. */
class Compiler {
  final FileSystem fileSystem;
  final CompilerOptions options;
  final List<SourceFile> files = <SourceFile>[];

  String _mainPath;
  String _packageRoot;
  String _resetCssFile;
  StyleSheet _cssResetStyleSheet;
  Messages _messages;

  FutureGroup _tasks;
  Set _processed;

  /** Information about source [files] given their href. */
  final Map<String, FileInfo> info = new SplayTreeMap<String, FileInfo>();

  final GlobalInfo global = new GlobalInfo();

  /** Creates a compiler with [options] using [fileSystem]. */
  Compiler(this.fileSystem, this.options, this._messages) {
    _mainPath = options.inputFile;
    var mainDir = path.dirname(_mainPath);
    var baseDir = options.baseDir != null ? options.baseDir : mainDir;
    _packageRoot = options.packageRoot != null ? options.packageRoot
        : path.join(path.dirname(_mainPath), 'packages');

    if (options.resetCssFile != null) {
      _resetCssFile = options.resetCssFile;
      if (path.isRelative(_resetCssFile)) {
        // If CSS reset file path is relative from our current path.
        _resetCssFile = path.resolve(_resetCssFile);
      }
    }

    // Normalize paths - all should be relative or absolute paths.
    if (path.isAbsolute(_mainPath) || path.isAbsolute(baseDir)
        || path.isAbsolute(_packageRoot)) {
      if (path.isRelative(_mainPath)) _mainPath = path.resolve(_mainPath);
      if (path.isRelative(baseDir)) baseDir = path.resolve(baseDir);
      if (path.isRelative(_packageRoot)) {
        _packageRoot = path.resolve(_packageRoot);
      }
    }
  }

  /** Compile the application starting from the given input file. */
  Future run() {
    if (path.basename(_mainPath).endsWith('.dart')) {
      _messages.error("Please provide an HTML file as your entry point.",
          null);
      return new Future.value(null);
    }
    return _parseAndDiscover(_mainPath).then((_) {
      _analyze();

      // Analyze all CSS files.
      _time('Analyzed Style Sheets', '', () =>
          analyzeCss(_packageRoot, files, info,
              global.pseudoElements, _messages,
              warningsAsErrors: options.warningsAsErrors));
    });
  }

  /**
   * Asynchronously parse [inputFile] and transitively discover web components
   * to load and parse. Returns a future that completes when all files are
   * processed.
   */
  Future _parseAndDiscover(String inputFile) {
    _tasks = new FutureGroup();
    _processed = new Set();
    _processed.add(inputFile);
    _tasks.add(_parseHtmlFile(new UrlInfo(inputFile, inputFile, null), true));
    return _tasks.future;
  }

  void _processHtmlFile(UrlInfo inputUrl, SourceFile file) {
    if (file == null) return;

    bool isEntryPoint = _processed.length == 1;

    files.add(file);

    var fileInfo = _time('Analyzed definitions', inputUrl.url, () {
      return analyzeDefinitions(global, inputUrl, file.document, _packageRoot,
        _messages);
    });
    info[inputUrl.resolvedPath] = fileInfo;

    if (isEntryPoint && _resetCssFile != null) {
      _processed.add(_resetCssFile);
      _tasks.add(_parseCssFile(new UrlInfo(_resetCssFile, _resetCssFile,
          null)));
    }

    // Load component files referenced by [file].
    for (var link in fileInfo.componentLinks) {
      _loadFile(link, _parseHtmlFile);
    }

    // Load stylesheet files referenced by [file].
    for (var link in fileInfo.styleSheetHrefs) {
      _loadFile(link, _parseCssFile);
    }

    // Process any @imports inside of a <style> tag.
    var urlInfos = findUrlsImported(fileInfo, fileInfo.inputUrl, _packageRoot,
        file.document, _messages, options);
    for (var urlInfo in urlInfos) {
      _loadFile(urlInfo, _parseCssFile);
    }

    // Load .dart files being referenced in components.
    for (var component in fileInfo.declaredComponents) {
      // Process any @imports inside of the <style> tag in a component.
      var urlInfos = findUrlsImported(component, fileInfo.inputUrl,
          _packageRoot, component.element, _messages, options);
      for (var urlInfo in urlInfos) {
        _loadFile(urlInfo, _parseCssFile);
      }
    }
  }

  /**
   * Helper function to load [urlInfo] and parse it using [loadAndParse] if it
   * hasn't been loaded before.
   */
  void _loadFile(UrlInfo urlInfo, Future loadAndParse(UrlInfo inputUrl)) {
    if (urlInfo == null) return;
    var resolvedPath = urlInfo.resolvedPath;
    if (!_processed.contains(resolvedPath)) {
      _processed.add(resolvedPath);
      _tasks.add(loadAndParse(urlInfo));
    }
  }

  /** Parse an HTML file. */
  Future _parseHtmlFile(UrlInfo inputUrl, [bool checkDocType = false]) {
    var filePath = inputUrl.resolvedPath;
    return fileSystem.readTextOrBytes(filePath)
        .catchError((e) => _readError(e, inputUrl))
        .then((source) {
          if (source == null) return;
          var file = new SourceFile(filePath);
          file.document = _time('Parsed', filePath,
              () => parseHtml(source, filePath, _messages, checkDocType));
          _processHtmlFile(inputUrl, file);
        });
  }

  /** Parse a stylesheet file. */
  Future _parseCssFile(UrlInfo inputUrl) {
    if (!options.emulateScopedCss) {
      return new Future<SourceFile>.value(null);
    }
    var filePath = inputUrl.resolvedPath;
    return fileSystem.readText(filePath)
        .catchError((e) => _readError(e, inputUrl, isWarning: true))
        .then((code) {
          if (code == null) return;
          var file = new SourceFile(filePath, type: SourceFile.STYLESHEET);
          file.code = code;
          _processCssFile(inputUrl, file);
        });
  }


  SourceFile _readError(error, UrlInfo inputUrl, {isWarning: false}) {
    var message = 'unable to open file "${inputUrl.resolvedPath}"';
    if (options.verbose) {
      message = '$message. original message:\n $error';
    }
    if (isWarning) {
      _messages.warning(message, inputUrl.sourceSpan);
    } else {
      _messages.error(message, inputUrl.sourceSpan);
    }
    return null;
  }

  void _processCssFile(UrlInfo inputUrl, SourceFile cssFile) {
    if (cssFile == null) return;

    files.add(cssFile);

    var fileInfo = new FileInfo(inputUrl);
    info[inputUrl.resolvedPath] = fileInfo;

    var styleSheet = parseCss(cssFile.code, _messages, options);
    if (inputUrl.url == _resetCssFile) {
      _cssResetStyleSheet = styleSheet;
    } else if (styleSheet != null) {
      _resolveStyleSheetImports(inputUrl, cssFile.path, styleSheet);
      fileInfo.styleSheets.add(styleSheet);
    }
  }

  /** Load and parse all style sheets referenced with an @imports. */
  void _resolveStyleSheetImports(UrlInfo inputUrl, String processingFile,
      StyleSheet styleSheet) {
    var urlInfos = _time('CSS imports', processingFile, () =>
        findImportsInStyleSheet(styleSheet, _packageRoot, inputUrl, _messages));

    for (var urlInfo in urlInfos) {
      if (urlInfo == null) break;
      // Load any @imported stylesheet files referenced in this style sheet.
      _loadFile(urlInfo, _parseCssFile);
    }
  }

  /** Run the analyzer on every input html file. */
  void _analyze() {
    var uniqueIds = new IntIterator();
    for (var file in files) {
      if (file.isHtml) {
        _time('Analyzed contents', file.path, () =>
            analyzeFile(file, info, uniqueIds, global, _messages,
              options.emulateScopedCss));
      }
    }
  }

  // TODO(jmesserly): refactor this and other CSS related transforms out of
  // Compiler.
  /**
   * Generate an CSS file for all style sheets (main and components).
   * Returns true if a file was generated, otherwise false.
   */
  bool _emitAllCss() {
    if (!options.emulateScopedCss) return false;

    var buff = new StringBuffer();

    // Emit all linked style sheet files first.
    for (var file in files) {
      var css = new StringBuffer();
      var fileInfo = info[file.path];
      if (file.isStyleSheet) {
        for (var styleSheet in fileInfo.styleSheets) {
          css.write(
              '/* Auto-generated from style sheet href = ${file.path} */\n'
              '/* DO NOT EDIT. */\n\n');
          css.write(emitStyleSheet(styleSheet, fileInfo));
          css.write('\n\n');
        }
      }
    }

    // Emit all CSS for each component (style scoped).
    for (var file in files) {
      if (file.isHtml) {
        var fileInfo = info[file.path];
        for (var component in fileInfo.declaredComponents) {
          for (var styleSheet in component.styleSheets) {
            // Translate any URIs in CSS.
            if (buff.isEmpty) {
              buff.write(
                  '/* Auto-generated from components style tags. */\n'
                  '/* DO NOT EDIT. */\n\n');
            }
            buff.write(
                '/* ==================================================== \n'
                '   Component ${component.tagName} stylesheet \n'
                '   ==================================================== */\n');

            var tagName = component.tagName;
            if (!component.hasAuthorStyles) {
              if (_cssResetStyleSheet != null) {
                // If component doesn't have apply-author-styles then we need to
                // reset the CSS the styles for the component (if css-reset file
                // option was passed).
                buff.write('\n/* Start CSS Reset */\n');
                var style;
                if (options.emulateScopedCss) {
                  style = emitComponentStyleSheet(_cssResetStyleSheet, tagName);
                } else {
                  style = emitOriginalCss(_cssResetStyleSheet);
                }
                buff.write(style);
                buff.write('/* End CSS Reset */\n\n');
              }
            }
            if (options.emulateScopedCss) {
              buff.write(emitComponentStyleSheet(styleSheet, tagName));
            } else {
              buff.write(emitOriginalCss(styleSheet));
            }
            buff.write('\n\n');
          }
        }
      }
    }

    if (buff.isEmpty) return false;
    return true;
  }

  _time(String logMessage, String filePath, callback(),
      {bool printTime: false}) {
    var message = new StringBuffer();
    message.write(logMessage);
    var filename = path.basename(filePath);
    for (int i = (60 - logMessage.length - filename.length); i > 0 ; i--) {
      message.write(' ');
    }
    message.write(filename);
    return time(message.toString(), callback,
        printTime: options.verbose || printTime);
  }
}
