/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var path = require('path'),
    mkdirp = require('mkdirp'),
    util = require('util'),
    fs = require('fs'),
    defaults = require('./common/defaults'),
    Report = require('./index'),
    TreeSummarizer = require('../util/tree-summarizer'),
    utils = require('../object-utils'),
    PCT_COLS = 9,
    MISSING_COL = 15,
    TAB_SIZE = 1,
    DELIM = ' |',
    COL_DELIM = '-|';

/**
 * a `Report` implementation that produces text output in a detailed table.
 *
 * Usage
 * -----
 *
 *      var report = require('istanbul').Report.create('text');
 *
 * @class TextReport
 * @extends Report
 * @module report
 * @constructor
 * @param {Object} opts optional
 * @param {String} [opts.dir] the directory in which to the text coverage report will be written, when writing to a file
 * @param {String} [opts.file] the filename for the report. When omitted, the report is written to console
 * @param {Number} [opts.maxCols] the max column width of the report. By default, the width of the report is adjusted based on the length of the paths
 *              to be reported.
 */
function TextReport(opts) {
    Report.call(this);
    opts = opts || {};
    this.dir = opts.dir || process.cwd();
    this.file = opts.file;
    this.summary = opts.summary;
    this.maxCols = opts.maxCols || 0;
    this.watermarks = opts.watermarks || defaults.watermarks();
}

TextReport.TYPE = 'text';
util.inherits(TextReport, Report);

function padding(num, ch) {
    var str = '',
        i;
    ch = ch || ' ';
    for (i = 0; i < num; i += 1) {
        str += ch;
    }
    return str;
}

function fill(str, width, right, tabs, clazz) {
    tabs = tabs || 0;
    str = String(str);

    var leadingSpaces = tabs * TAB_SIZE,
        remaining = width - leadingSpaces,
        leader = padding(leadingSpaces),
        fmtStr = '',
        fillStr,
        strlen = str.length;

    if (remaining > 0) {
        if (remaining >= strlen) {
            fillStr = padding(remaining - strlen);
            fmtStr = right ? fillStr + str : str + fillStr;
        } else {
            fmtStr = str.substring(strlen - remaining);
            fmtStr = '... ' + fmtStr.substring(4);
        }
    }

    fmtStr = defaults.colorize(fmtStr, clazz);
    return leader + fmtStr;
}

function formatName(name, maxCols, level, clazz) {
    return fill(name, maxCols, false, level, clazz);
}

function formatPct(pct, clazz, width) {
    return fill(pct, width || PCT_COLS, true, 0, clazz);
}

function nodeName(node) {
    return node.displayShortName() || 'All files';
}

function tableHeader(maxNameCols) {
    var elements = [];
    elements.push(formatName('File', maxNameCols, 0));
    elements.push(formatPct('% Stmts'));
    elements.push(formatPct('% Branch'));
    elements.push(formatPct('% Funcs'));
    elements.push(formatPct('% Lines'));
    elements.push(formatPct('Uncovered Lines', undefined, MISSING_COL));
    return elements.join(' |') + ' |';
}

function collectMissingLines(kind, linesCovered) {
  var missingLines = [];

  if (kind !== 'file') {
      return [];
  }

  Object.keys(linesCovered).forEach(function (key) {
      if (!linesCovered[key]) {
          missingLines.push(key);
      }
  });

  return missingLines;
}

function tableRow(node, maxNameCols, level, watermarks) {
    var name = nodeName(node),
        statements = node.metrics.statements.pct,
        branches = node.metrics.branches.pct,
        functions = node.metrics.functions.pct,
        lines = node.metrics.lines.pct,
        missingLines = collectMissingLines(node.kind, node.metrics.linesCovered),
        elements = [];

    elements.push(formatName(name, maxNameCols, level, defaults.classFor('statements', node.metrics, watermarks)));
    elements.push(formatPct(statements, defaults.classFor('statements', node.metrics, watermarks)));
    elements.push(formatPct(branches, defaults.classFor('branches', node.metrics, watermarks)));
    elements.push(formatPct(functions, defaults.classFor('functions', node.metrics, watermarks)));
    elements.push(formatPct(lines, defaults.classFor('lines', node.metrics, watermarks)));
    elements.push(formatPct(missingLines.join(','), 'low', MISSING_COL));

    return elements.join(DELIM) + DELIM;
}

function findNameWidth(node, level, last) {
    last = last || 0;
    level = level || 0;
    var idealWidth = TAB_SIZE * level + nodeName(node).length;
    if (idealWidth > last) {
        last = idealWidth;
    }
    node.children.forEach(function (child) {
        last = findNameWidth(child, level + 1, last);
    });
    return last;
}

function makeLine(nameWidth) {
    var name = padding(nameWidth, '-'),
        pct = padding(PCT_COLS, '-'),
        elements = [];

    elements.push(name);
    elements.push(pct);
    elements.push(pct);
    elements.push(pct);
    elements.push(pct);
    elements.push(padding(MISSING_COL, '-'));
    return elements.join(COL_DELIM) + COL_DELIM;
}

function walk(node, nameWidth, array, level, watermarks) {
    var line;
    if (level === 0) {
        line = makeLine(nameWidth);
        array.push(line);
        array.push(tableHeader(nameWidth));
        array.push(line);
    } else {
        array.push(tableRow(node, nameWidth, level, watermarks));
    }
    node.children.forEach(function (child) {
        walk(child, nameWidth, array, level + 1, watermarks);
    });
    if (level === 0) {
        array.push(line);
        array.push(tableRow(node, nameWidth, level, watermarks));
        array.push(line);
    }
}

Report.mix(TextReport, {
    synopsis: function () {
        return 'text report that prints a coverage line for every file, typically to console';
    },
    getDefaultConfig: function () {
        return { file: null, maxCols: 0 };
    },
    writeReport: function (collector /*, sync */) {
        var summarizer = new TreeSummarizer(),
            tree,
            root,
            nameWidth,
            statsWidth = 4 * (PCT_COLS + 2) + MISSING_COL,
            maxRemaining,
            strings = [],
            text;

        collector.files().forEach(function (key) {
            summarizer.addFileCoverageSummary(key, utils.summarizeFileCoverage(
                collector.fileCoverageFor(key)
            ));
        });
        tree = summarizer.getTreeSummary();
        root = tree.root;
        nameWidth = findNameWidth(root);
        if (this.maxCols > 0) {
            maxRemaining = this.maxCols - statsWidth - 2;
            if (nameWidth > maxRemaining) {
                nameWidth = maxRemaining;
            }
        }
        walk(root, nameWidth, strings, 0, this.watermarks);
        text = strings.join('\n') + '\n';
        if (this.file) {
            mkdirp.sync(this.dir);
            fs.writeFileSync(path.join(this.dir, this.file), text, 'utf8');
        } else {
            console.log(text);
        }
        this.emit('done');
    }
});

module.exports = TextReport;
