var assert = require("assert");
var sourceMap = require("source-map");
var normalizeOptions = require("./options").normalize;
var secretKey = require("private").makeUniqueKey();
var types = require("./types");
var isString = types.builtInTypes.string;
var comparePos = require("./util").comparePos;
var Mapping = require("./mapping");

// Goals:
// 1. Minimize new string creation.
// 2. Keep (de)identation O(lines) time.
// 3. Permit negative indentations.
// 4. Enforce immutability.
// 5. No newline characters.

function getSecret(lines) {
    return lines[secretKey];
}

function Lines(infos, sourceFileName) {
    assert.ok(this instanceof Lines);
    assert.ok(infos.length > 0);

    if (sourceFileName) {
        isString.assert(sourceFileName);
    } else {
        sourceFileName = null;
    }

    Object.defineProperty(this, secretKey, {
        value: {
            infos: infos,
            mappings: [],
            name: sourceFileName,
            cachedSourceMap: null
        }
    });

    if (sourceFileName) {
        getSecret(this).mappings.push(new Mapping(this, {
            start: this.firstPos(),
            end: this.lastPos()
        }));
    }
}

// Exposed for instanceof checks. The fromString function should be used
// to create new Lines objects.
exports.Lines = Lines;
var Lp = Lines.prototype;

// These properties used to be assigned to each new object in the Lines
// constructor, but we can more efficiently stuff them into the secret and
// let these lazy accessors compute their values on-the-fly.
Object.defineProperties(Lp, {
    length: {
        get: function() {
            return getSecret(this).infos.length;
        }
    },

    name: {
        get: function() {
            return getSecret(this).name;
        }
    }
});

function copyLineInfo(info) {
    return {
        line: info.line,
        indent: info.indent,
        locked: info.locked,
        sliceStart: info.sliceStart,
        sliceEnd: info.sliceEnd
    };
}

var fromStringCache = {};
var hasOwn = fromStringCache.hasOwnProperty;
var maxCacheKeyLen = 10;

function countSpaces(spaces, tabWidth) {
    var count = 0;
    var len = spaces.length;

    for (var i = 0; i < len; ++i) {
        switch (spaces.charCodeAt(i)) {
        case 9: // '\t'
            assert.strictEqual(typeof tabWidth, "number");
            assert.ok(tabWidth > 0);

            var next = Math.ceil(count / tabWidth) * tabWidth;
            if (next === count) {
                count += tabWidth;
            } else {
                count = next;
            }

            break;

        case 11: // '\v'
        case 12: // '\f'
        case 13: // '\r'
        case 0xfeff: // zero-width non-breaking space
            // These characters contribute nothing to indentation.
            break;

        case 32: // ' '
        default: // Treat all other whitespace like ' '.
            count += 1;
            break;
        }
    }

    return count;
}
exports.countSpaces = countSpaces;

var leadingSpaceExp = /^\s*/;

// As specified here: http://www.ecma-international.org/ecma-262/6.0/#sec-line-terminators
var lineTerminatorSeqExp =
    /\u000D\u000A|\u000D(?!\u000A)|\u000A|\u2028|\u2029/;

/**
 * @param {Object} options - Options object that configures printing.
 */
function fromString(string, options) {
    if (string instanceof Lines)
        return string;

    string += "";

    var tabWidth = options && options.tabWidth;
    var tabless = string.indexOf("\t") < 0;
    var locked = !! (options && options.locked);
    var cacheable = !options && tabless && (string.length <= maxCacheKeyLen);

    assert.ok(tabWidth || tabless, "No tab width specified but encountered tabs in string\n" + string);

    if (cacheable && hasOwn.call(fromStringCache, string))
        return fromStringCache[string];

    var lines = new Lines(string.split(lineTerminatorSeqExp).map(function(line) {
        var spaces = leadingSpaceExp.exec(line)[0];
        return {
            line: line,
            indent: countSpaces(spaces, tabWidth),
            // Boolean indicating whether this line can be reindented.
            locked: locked,
            sliceStart: spaces.length,
            sliceEnd: line.length
        };
    }), normalizeOptions(options).sourceFileName);

    if (cacheable)
        fromStringCache[string] = lines;

    return lines;
}
exports.fromString = fromString;

function isOnlyWhitespace(string) {
    return !/\S/.test(string);
}

Lp.toString = function(options) {
    return this.sliceString(this.firstPos(), this.lastPos(), options);
};

Lp.getSourceMap = function(sourceMapName, sourceRoot) {
    if (!sourceMapName) {
        // Although we could make up a name or generate an anonymous
        // source map, instead we assume that any consumer who does not
        // provide a name does not actually want a source map.
        return null;
    }

    var targetLines = this;

    function updateJSON(json) {
        json = json || {};

        isString.assert(sourceMapName);
        json.file = sourceMapName;

        if (sourceRoot) {
            isString.assert(sourceRoot);
            json.sourceRoot = sourceRoot;
        }

        return json;
    }

    var secret = getSecret(targetLines);
    if (secret.cachedSourceMap) {
        // Since Lines objects are immutable, we can reuse any source map
        // that was previously generated. Nevertheless, we return a new
        // JSON object here to protect the cached source map from outside
        // modification.
        return updateJSON(secret.cachedSourceMap.toJSON());
    }

    var smg = new sourceMap.SourceMapGenerator(updateJSON());
    var sourcesToContents = {};

    secret.mappings.forEach(function(mapping) {
        var sourceCursor = mapping.sourceLines.skipSpaces(
            mapping.sourceLoc.start
        ) || mapping.sourceLines.lastPos();

        var targetCursor = targetLines.skipSpaces(
            mapping.targetLoc.start
        ) || targetLines.lastPos();

        while (comparePos(sourceCursor, mapping.sourceLoc.end) < 0 &&
               comparePos(targetCursor, mapping.targetLoc.end) < 0) {

            var sourceChar = mapping.sourceLines.charAt(sourceCursor);
            var targetChar = targetLines.charAt(targetCursor);
            assert.strictEqual(sourceChar, targetChar);

            var sourceName = mapping.sourceLines.name;

            // Add mappings one character at a time for maximum resolution.
            smg.addMapping({
                source: sourceName,
                original: { line: sourceCursor.line,
                            column: sourceCursor.column },
                generated: { line: targetCursor.line,
                             column: targetCursor.column }
            });

            if (!hasOwn.call(sourcesToContents, sourceName)) {
                var sourceContent = mapping.sourceLines.toString();
                smg.setSourceContent(sourceName, sourceContent);
                sourcesToContents[sourceName] = sourceContent;
            }

            targetLines.nextPos(targetCursor, true);
            mapping.sourceLines.nextPos(sourceCursor, true);
        }
    });

    secret.cachedSourceMap = smg;

    return smg.toJSON();
};

Lp.bootstrapCharAt = function(pos) {
    assert.strictEqual(typeof pos, "object");
    assert.strictEqual(typeof pos.line, "number");
    assert.strictEqual(typeof pos.column, "number");

    var line = pos.line,
        column = pos.column,
        strings = this.toString().split(lineTerminatorSeqExp),
        string = strings[line - 1];

    if (typeof string === "undefined")
        return "";

    if (column === string.length &&
        line < strings.length)
        return "\n";

    if (column >= string.length)
        return "";

    return string.charAt(column);
};

Lp.charAt = function(pos) {
    assert.strictEqual(typeof pos, "object");
    assert.strictEqual(typeof pos.line, "number");
    assert.strictEqual(typeof pos.column, "number");

    var line = pos.line,
        column = pos.column,
        secret = getSecret(this),
        infos = secret.infos,
        info = infos[line - 1],
        c = column;

    if (typeof info === "undefined" || c < 0)
        return "";

    var indent = this.getIndentAt(line);
    if (c < indent)
        return " ";

    c += info.sliceStart - indent;

    if (c === info.sliceEnd &&
        line < this.length)
        return "\n";

    if (c >= info.sliceEnd)
        return "";

    return info.line.charAt(c);
};

Lp.stripMargin = function(width, skipFirstLine) {
    if (width === 0)
        return this;

    assert.ok(width > 0, "negative margin: " + width);

    if (skipFirstLine && this.length === 1)
        return this;

    var secret = getSecret(this);

    var lines = new Lines(secret.infos.map(function(info, i) {
        if (info.line && (i > 0 || !skipFirstLine)) {
            info = copyLineInfo(info);
            info.indent = Math.max(0, info.indent - width);
        }
        return info;
    }));

    if (secret.mappings.length > 0) {
        var newMappings = getSecret(lines).mappings;
        assert.strictEqual(newMappings.length, 0);
        secret.mappings.forEach(function(mapping) {
            newMappings.push(mapping.indent(width, skipFirstLine, true));
        });
    }

    return lines;
};

Lp.indent = function(by) {
    if (by === 0)
        return this;

    var secret = getSecret(this);

    var lines = new Lines(secret.infos.map(function(info) {
        if (info.line && ! info.locked) {
            info = copyLineInfo(info);
            info.indent += by;
        }
        return info
    }));

    if (secret.mappings.length > 0) {
        var newMappings = getSecret(lines).mappings;
        assert.strictEqual(newMappings.length, 0);
        secret.mappings.forEach(function(mapping) {
            newMappings.push(mapping.indent(by));
        });
    }

    return lines;
};

Lp.indentTail = function(by) {
    if (by === 0)
        return this;

    if (this.length < 2)
        return this;

    var secret = getSecret(this);

    var lines = new Lines(secret.infos.map(function(info, i) {
        if (i > 0 && info.line && ! info.locked) {
            info = copyLineInfo(info);
            info.indent += by;
        }

        return info;
    }));

    if (secret.mappings.length > 0) {
        var newMappings = getSecret(lines).mappings;
        assert.strictEqual(newMappings.length, 0);
        secret.mappings.forEach(function(mapping) {
            newMappings.push(mapping.indent(by, true));
        });
    }

    return lines;
};

Lp.lockIndentTail = function () {
    if (this.length < 2) {
        return this;
    }

    var infos = getSecret(this).infos;

    return new Lines(infos.map(function (info, i) {
        info = copyLineInfo(info);
        info.locked = i > 0;
        return info;
    }));
};

Lp.getIndentAt = function(line) {
    assert.ok(line >= 1, "no line " + line + " (line numbers start from 1)");
    var secret = getSecret(this),
        info = secret.infos[line - 1];
    return Math.max(info.indent, 0);
};

Lp.guessTabWidth = function() {
    var secret = getSecret(this);
    if (hasOwn.call(secret, "cachedTabWidth")) {
        return secret.cachedTabWidth;
    }

    var counts = []; // Sparse array.
    var lastIndent = 0;

    for (var line = 1, last = this.length; line <= last; ++line) {
        var info = secret.infos[line - 1];
        var sliced = info.line.slice(info.sliceStart, info.sliceEnd);

        // Whitespace-only lines don't tell us much about the likely tab
        // width of this code.
        if (isOnlyWhitespace(sliced)) {
            continue;
        }

        var diff = Math.abs(info.indent - lastIndent);
        counts[diff] = ~~counts[diff] + 1;
        lastIndent = info.indent;
    }

    var maxCount = -1;
    var result = 2;

    for (var tabWidth = 1;
         tabWidth < counts.length;
         tabWidth += 1) {
        if (hasOwn.call(counts, tabWidth) &&
            counts[tabWidth] > maxCount) {
            maxCount = counts[tabWidth];
            result = tabWidth;
        }
    }

    return secret.cachedTabWidth = result;
};

// Determine if the list of lines has a first line that starts with a //
// or /* comment. If this is the case, the code may need to be wrapped in
// parens to avoid ASI issues.
Lp.startsWithComment = function () {
    var secret = getSecret(this);
    if (secret.infos.length === 0) {
        return false;
    }
    var firstLineInfo = secret.infos[0],
        sliceStart = firstLineInfo.sliceStart,
        sliceEnd = firstLineInfo.sliceEnd,
        firstLine = firstLineInfo.line.slice(sliceStart, sliceEnd).trim();
    return firstLine.length === 0 ||
        firstLine.slice(0, 2) === "//" ||
        firstLine.slice(0, 2) === "/*";
};

Lp.isOnlyWhitespace = function() {
    return isOnlyWhitespace(this.toString());
};

Lp.isPrecededOnlyByWhitespace = function(pos) {
    var secret = getSecret(this);
    var info = secret.infos[pos.line - 1];
    var indent = Math.max(info.indent, 0);

    var diff = pos.column - indent;
    if (diff <= 0) {
        // If pos.column does not exceed the indentation amount, then
        // there must be only whitespace before it.
        return true;
    }

    var start = info.sliceStart;
    var end = Math.min(start + diff, info.sliceEnd);
    var prefix = info.line.slice(start, end);

    return isOnlyWhitespace(prefix);
};

Lp.getLineLength = function(line) {
    var secret = getSecret(this),
        info = secret.infos[line - 1];
    return this.getIndentAt(line) + info.sliceEnd - info.sliceStart;
};

Lp.nextPos = function(pos, skipSpaces) {
    var l = Math.max(pos.line, 0),
        c = Math.max(pos.column, 0);

    if (c < this.getLineLength(l)) {
        pos.column += 1;

        return skipSpaces
            ? !!this.skipSpaces(pos, false, true)
            : true;
    }

    if (l < this.length) {
        pos.line += 1;
        pos.column = 0;

        return skipSpaces
            ? !!this.skipSpaces(pos, false, true)
            : true;
    }

    return false;
};

Lp.prevPos = function(pos, skipSpaces) {
    var l = pos.line,
        c = pos.column;

    if (c < 1) {
        l -= 1;

        if (l < 1)
            return false;

        c = this.getLineLength(l);

    } else {
        c = Math.min(c - 1, this.getLineLength(l));
    }

    pos.line = l;
    pos.column = c;

    return skipSpaces
        ? !!this.skipSpaces(pos, true, true)
        : true;
};

Lp.firstPos = function() {
    // Trivial, but provided for completeness.
    return { line: 1, column: 0 };
};

Lp.lastPos = function() {
    return {
        line: this.length,
        column: this.getLineLength(this.length)
    };
};

Lp.skipSpaces = function(pos, backward, modifyInPlace) {
    if (pos) {
        pos = modifyInPlace ? pos : {
            line: pos.line,
            column: pos.column
        };
    } else if (backward) {
        pos = this.lastPos();
    } else {
        pos = this.firstPos();
    }

    if (backward) {
        while (this.prevPos(pos)) {
            if (!isOnlyWhitespace(this.charAt(pos)) &&
                this.nextPos(pos)) {
                return pos;
            }
        }

        return null;

    } else {
        while (isOnlyWhitespace(this.charAt(pos))) {
            if (!this.nextPos(pos)) {
                return null;
            }
        }

        return pos;
    }
};

Lp.trimLeft = function() {
    var pos = this.skipSpaces(this.firstPos(), false, true);
    return pos ? this.slice(pos) : emptyLines;
};

Lp.trimRight = function() {
    var pos = this.skipSpaces(this.lastPos(), true, true);
    return pos ? this.slice(this.firstPos(), pos) : emptyLines;
};

Lp.trim = function() {
    var start = this.skipSpaces(this.firstPos(), false, true);
    if (start === null)
        return emptyLines;

    var end = this.skipSpaces(this.lastPos(), true, true);
    assert.notStrictEqual(end, null);

    return this.slice(start, end);
};

Lp.eachPos = function(callback, startPos, skipSpaces) {
    var pos = this.firstPos();

    if (startPos) {
        pos.line = startPos.line,
        pos.column = startPos.column
    }

    if (skipSpaces && !this.skipSpaces(pos, false, true)) {
        return; // Encountered nothing but spaces.
    }

    do callback.call(this, pos);
    while (this.nextPos(pos, skipSpaces));
};

Lp.bootstrapSlice = function(start, end) {
    var strings = this.toString().split(
        lineTerminatorSeqExp
    ).slice(
        start.line - 1,
        end.line
    );

    strings.push(strings.pop().slice(0, end.column));
    strings[0] = strings[0].slice(start.column);

    return fromString(strings.join("\n"));
};

Lp.slice = function(start, end) {
    if (!end) {
        if (!start) {
            // The client seems to want a copy of this Lines object, but
            // Lines objects are immutable, so it's perfectly adequate to
            // return the same object.
            return this;
        }

        // Slice to the end if no end position was provided.
        end = this.lastPos();
    }

    var secret = getSecret(this);
    var sliced = secret.infos.slice(start.line - 1, end.line);

    if (start.line === end.line) {
        sliced[0] = sliceInfo(sliced[0], start.column, end.column);
    } else {
        assert.ok(start.line < end.line);
        sliced[0] = sliceInfo(sliced[0], start.column);
        sliced.push(sliceInfo(sliced.pop(), 0, end.column));
    }

    var lines = new Lines(sliced);

    if (secret.mappings.length > 0) {
        var newMappings = getSecret(lines).mappings;
        assert.strictEqual(newMappings.length, 0);
        secret.mappings.forEach(function(mapping) {
            var sliced = mapping.slice(this, start, end);
            if (sliced) {
                newMappings.push(sliced);
            }
        }, this);
    }

    return lines;
};

function sliceInfo(info, startCol, endCol) {
    var sliceStart = info.sliceStart;
    var sliceEnd = info.sliceEnd;
    var indent = Math.max(info.indent, 0);
    var lineLength = indent + sliceEnd - sliceStart;

    if (typeof endCol === "undefined") {
        endCol = lineLength;
    }

    startCol = Math.max(startCol, 0);
    endCol = Math.min(endCol, lineLength);
    endCol = Math.max(endCol, startCol);

    if (endCol < indent) {
        indent = endCol;
        sliceEnd = sliceStart;
    } else {
        sliceEnd -= lineLength - endCol;
    }

    lineLength = endCol;
    lineLength -= startCol;

    if (startCol < indent) {
        indent -= startCol;
    } else {
        startCol -= indent;
        indent = 0;
        sliceStart += startCol;
    }

    assert.ok(indent >= 0);
    assert.ok(sliceStart <= sliceEnd);
    assert.strictEqual(lineLength, indent + sliceEnd - sliceStart);

    if (info.indent === indent &&
        info.sliceStart === sliceStart &&
        info.sliceEnd === sliceEnd) {
        return info;
    }

    return {
        line: info.line,
        indent: indent,
        // A destructive slice always unlocks indentation.
        locked: false,
        sliceStart: sliceStart,
        sliceEnd: sliceEnd
    };
}

Lp.bootstrapSliceString = function(start, end, options) {
    return this.slice(start, end).toString(options);
};

Lp.sliceString = function(start, end, options) {
    if (!end) {
        if (!start) {
            // The client seems to want a copy of this Lines object, but
            // Lines objects are immutable, so it's perfectly adequate to
            // return the same object.
            return this;
        }

        // Slice to the end if no end position was provided.
        end = this.lastPos();
    }

    options = normalizeOptions(options);

    var infos = getSecret(this).infos;
    var parts = [];
    var tabWidth = options.tabWidth;

    for (var line = start.line; line <= end.line; ++line) {
        var info = infos[line - 1];

        if (line === start.line) {
            if (line === end.line) {
                info = sliceInfo(info, start.column, end.column);
            } else {
                info = sliceInfo(info, start.column);
            }
        } else if (line === end.line) {
            info = sliceInfo(info, 0, end.column);
        }

        var indent = Math.max(info.indent, 0);

        var before = info.line.slice(0, info.sliceStart);
        if (options.reuseWhitespace &&
            isOnlyWhitespace(before) &&
            countSpaces(before, options.tabWidth) === indent) {
            // Reuse original spaces if the indentation is correct.
            parts.push(info.line.slice(0, info.sliceEnd));
            continue;
        }

        var tabs = 0;
        var spaces = indent;

        if (options.useTabs) {
            tabs = Math.floor(indent / tabWidth);
            spaces -= tabs * tabWidth;
        }

        var result = "";

        if (tabs > 0) {
            result += new Array(tabs + 1).join("\t");
        }

        if (spaces > 0) {
            result += new Array(spaces + 1).join(" ");
        }

        result += info.line.slice(info.sliceStart, info.sliceEnd);

        parts.push(result);
    }

    return parts.join(options.lineTerminator);
};

Lp.isEmpty = function() {
    return this.length < 2 && this.getLineLength(1) < 1;
};

Lp.join = function(elements) {
    var separator = this;
    var separatorSecret = getSecret(separator);
    var infos = [];
    var mappings = [];
    var prevInfo;

    function appendSecret(secret) {
        if (secret === null)
            return;

        if (prevInfo) {
            var info = secret.infos[0];
            var indent = new Array(info.indent + 1).join(" ");
            var prevLine = infos.length;
            var prevColumn = Math.max(prevInfo.indent, 0) +
                prevInfo.sliceEnd - prevInfo.sliceStart;

            prevInfo.line = prevInfo.line.slice(
                0, prevInfo.sliceEnd) + indent + info.line.slice(
                    info.sliceStart, info.sliceEnd);

            // If any part of a line is indentation-locked, the whole line
            // will be indentation-locked.
            prevInfo.locked = prevInfo.locked || info.locked;

            prevInfo.sliceEnd = prevInfo.line.length;

            if (secret.mappings.length > 0) {
                secret.mappings.forEach(function(mapping) {
                    mappings.push(mapping.add(prevLine, prevColumn));
                });
            }

        } else if (secret.mappings.length > 0) {
            mappings.push.apply(mappings, secret.mappings);
        }

        secret.infos.forEach(function(info, i) {
            if (!prevInfo || i > 0) {
                prevInfo = copyLineInfo(info);
                infos.push(prevInfo);
            }
        });
    }

    function appendWithSeparator(secret, i) {
        if (i > 0)
            appendSecret(separatorSecret);
        appendSecret(secret);
    }

    elements.map(function(elem) {
        var lines = fromString(elem);
        if (lines.isEmpty())
            return null;
        return getSecret(lines);
    }).forEach(separator.isEmpty()
               ? appendSecret
               : appendWithSeparator);

    if (infos.length < 1)
        return emptyLines;

    var lines = new Lines(infos);

    getSecret(lines).mappings = mappings;

    return lines;
};

exports.concat = function(elements) {
    return emptyLines.join(elements);
};

Lp.concat = function(other) {
    var args = arguments,
        list = [this];
    list.push.apply(list, args);
    assert.strictEqual(list.length, args.length + 1);
    return emptyLines.join(list);
};

// The emptyLines object needs to be created all the way down here so that
// Lines.prototype will be fully populated.
var emptyLines = fromString("");
