/*
 * Copyright (C) 2015 Andy VanWagoner <andy@vanwagoner.family>.
 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>
 * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

function match(regexp)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.match requires that |this| not be null or undefined");

    if (regexp != null) {
        var matcher = regexp.@@match;
        if (matcher != @undefined)
            return matcher.@call(regexp, this);
    }

    var thisString = @toString(this);
    var createdRegExp = @regExpCreate(regexp, @undefined);
    return createdRegExp.@@match(thisString);
}

function matchAll(arg)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.matchAll requires |this| not to be null nor undefined");

    if (!@isUndefinedOrNull(arg)) {
        if (@isRegExp(arg) && !@stringIncludesInternal.@call(@toString(arg.flags), "g"))
            @throwTypeError("String.prototype.matchAll argument must not be a non-global regular expression");

        var matcher = arg.@@matchAll;
        if (!@isUndefinedOrNull(matcher))
            return matcher.@call(arg, this);
    }

    var string = @toString(this);
    var regExp = @regExpCreate(arg, "g");
    return regExp.@@matchAll(string);
}

@globalPrivate
function repeatSlowPath(string, count)
{
    "use strict";

    // Return an empty string.
    if (count === 0 || string.length === 0)
        return "";

    // Return the original string.
    if (count === 1)
        return string;

    if (string.length * count > @MAX_STRING_LENGTH)
        @throwOutOfMemoryError();

    // Bit operation onto |count| is safe because |count| should be within Int32 range,
    // Repeat log N times to generate the repeated string rope.
    var result = "";
    var operand = string;
    while (true) {
        if (count & 1)
            result += operand;
        count >>= 1;
        if (!count)
            return result;
        operand += operand;
    }
}

@globalPrivate
function repeatCharactersSlowPath(string, count)
{
    "use strict";
    var repeatCount = (count / string.length) | 0;
    var remainingCharacters = count - repeatCount * string.length;
    var result = "";
    var operand = string;
    // Bit operation onto |repeatCount| is safe because |repeatCount| should be within Int32 range,
    // Repeat log N times to generate the repeated string rope.
    while (true) {
        if (repeatCount & 1)
            result += operand;
        repeatCount >>= 1;
        if (!repeatCount)
            break;
        operand += operand;
    }
    if (remainingCharacters)
        result += @stringSubstringInternal.@call(string, 0, remainingCharacters);
    return result;
}


function repeat(count)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.repeat requires that |this| not be null or undefined");

    var string = @toString(this);
    count = @toInteger(count);

    if (count < 0 || count === @Infinity)
        @throwRangeError("String.prototype.repeat argument must be greater than or equal to 0 and not be Infinity");

    if (string.length === 1)
        return @repeatCharacter(string, count);

    return @repeatSlowPath(string, count);
}

function padStart(maxLength/*, fillString*/)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.padStart requires that |this| not be null or undefined");

    var string = @toString(this);
    maxLength = @toLength(maxLength);

    var stringLength = string.length;
    if (maxLength <= stringLength)
        return string;

    var filler;
    var fillString = @argument(1);
    if (fillString === @undefined)
        filler = " ";
    else {
        filler = @toString(fillString);
        if (filler === "")
            return string;
    }

    if (maxLength > @MAX_STRING_LENGTH)
        @throwOutOfMemoryError();

    var fillLength = maxLength - stringLength;
    var truncatedStringFiller;

    if (filler.length === 1)
        truncatedStringFiller = @repeatCharacter(filler, fillLength);
    else
        truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
    return truncatedStringFiller + string;
}

function padEnd(maxLength/*, fillString*/)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.padEnd requires that |this| not be null or undefined");

    var string = @toString(this);
    maxLength = @toLength(maxLength);

    var stringLength = string.length;
    if (maxLength <= stringLength)
        return string;

    var filler;
    var fillString = @argument(1);
    if (fillString === @undefined)
        filler = " ";
    else {
        filler = @toString(fillString);
        if (filler === "")
            return string;
    }

    if (maxLength > @MAX_STRING_LENGTH)
        @throwOutOfMemoryError();

    var fillLength = maxLength - stringLength;
    var truncatedStringFiller;

    if (filler.length === 1)
        truncatedStringFiller = @repeatCharacter(filler, fillLength);
    else
        truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
    return string + truncatedStringFiller;
}

@globalPrivate
function hasObservableSideEffectsForStringReplace(regexp, replacer)
{
    "use strict";

    if (!@isRegExpObject(regexp))
        return true;

    if (replacer !== @regExpPrototypeSymbolReplace)
        return true;
    
    var regexpExec = @tryGetById(regexp, "exec");
    if (regexpExec !== @regExpBuiltinExec)
        return true;

    var regexpGlobal = @tryGetById(regexp, "global");
    if (regexpGlobal !== @regExpProtoGlobalGetter)
        return true;

    var regexpUnicode = @tryGetById(regexp, "unicode");
    if (regexpUnicode !== @regExpProtoUnicodeGetter)
        return true;

    return typeof regexp.lastIndex !== "number";
}

@intrinsic=StringPrototypeReplaceIntrinsic
function replace(search, replace)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.replace requires that |this| not be null or undefined");

    if (search != null) {
        var replacer = search.@@replace;
        if (replacer !== @undefined) {
            if (!@hasObservableSideEffectsForStringReplace(search, replacer))
                return @toString(this).@replaceUsingRegExp(search, replace);
            return replacer.@call(search, this, replace);
        }
    }

    var thisString = @toString(this);
    var searchString = @toString(search);
    return thisString.@replaceUsingStringSearch(searchString, replace);
}

function replaceAll(search, replace)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.replaceAll requires |this| not to be null nor undefined");

    if (search != null) {
        if (@isRegExp(search) && !@stringIncludesInternal.@call(@toString(search.flags), "g"))
            @throwTypeError("String.prototype.replaceAll argument must not be a non-global regular expression");

        var replacer = search.@@replace;
        if (replacer !== @undefined) {
            if (!@hasObservableSideEffectsForStringReplace(search, replacer))
                return @toString(this).@replaceUsingRegExp(search, replace);
            return replacer.@call(search, this, replace);
        }
    }

    var thisString = @toString(this);
    var searchString = @toString(search);
    return thisString.@replaceAllUsingStringSearch(searchString, replace);
}

function search(regexp)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.search requires that |this| not be null or undefined");

    if (regexp != null) {
        var searcher = regexp.@@search;
        if (searcher != @undefined)
            return searcher.@call(regexp, this);
    }

    var thisString = @toString(this);
    var createdRegExp = @regExpCreate(regexp, @undefined);
    return createdRegExp.@@search(thisString);
}

function split(separator, limit)
{
    "use strict";
    
    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.split requires that |this| not be null or undefined");
    
    if (separator != null) {
        var splitter = separator.@@split;
        if (splitter != @undefined)
            return splitter.@call(separator, this, limit);
    }
    
    return @stringSplitFast.@call(this, separator, limit);
}

@globalPrivate
function stringConcatSlowPath()
{
    "use strict";

    var result = @toString(this);
    for (var i = 0, length = arguments.length; i < length; ++i)
        result += @toString(arguments[i]);
    return result;
}

function concat(arg /* ... */)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.concat requires that |this| not be null or undefined");

    if (@argumentCount() === 1)
        return @toString(this) + @toString(arg);
    return @tailCallForwardArguments(@stringConcatSlowPath, this);
}

@globalPrivate
function createHTML(func, string, tag, attribute, value)
{
    "use strict";
    if (@isUndefinedOrNull(string))
        @throwTypeError(`${func} requires that |this| not be null or undefined`);
    var S = @toString(string);
    var p1 = "<" + tag;
    if (attribute) {
        var V = @toString(value);
        var escapedV = V.@replaceUsingRegExp(/"/g, '&quot;');
        p1 = p1 + " " + @toString(attribute) + '="' + escapedV + '"'
    }
    var p2 = p1 + ">"
    var p3 = p2 + S;
    var p4 = p3 + "</" + tag + ">";
    return p4;
}

function anchor(url)
{
    "use strict";
    return @createHTML("String.prototype.link", this, "a", "name", url)
}

function big()
{
    "use strict";
    return @createHTML("String.prototype.big", this, "big", "", "");
}

function blink()
{
    "use strict";
    return @createHTML("String.prototype.blink", this, "blink", "", "");
}

function bold()
{
    "use strict";
    return @createHTML("String.prototype.bold", this, "b", "", "");
}

function fixed()
{
    "use strict";
    return @createHTML("String.prototype.fixed", this, "tt", "", "");
}

function fontcolor(color)
{
    "use strict";
    return @createHTML("String.prototype.fontcolor", this, "font", "color", color);
}

function fontsize(size)
{
    "use strict";
    return @createHTML("String.prototype.fontsize", this, "font", "size", size);
}

function italics()
{
    "use strict";
    return @createHTML("String.prototype.italics", this, "i", "", "");
}

function link(url)
{
    "use strict";
    return @createHTML("String.prototype.link", this, "a", "href", url)
}

function small()
{
    "use strict";
    return @createHTML("String.prototype.small", this, "small", "", "");
}

function strike()
{
    "use strict";
    return @createHTML("String.prototype.strike", this, "strike", "", "");
}

function sub()
{
    "use strict";
    return @createHTML("String.prototype.sub", this, "sub", "", "");
}

function sup()
{
    "use strict";
    return @createHTML("String.prototype.sup", this, "sup", "", "");
}
