/*
 *  Copyright (c) 2018, The OpenThread Authors.
 *  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.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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.
 */

/**
 * @file
 *  This file implements OpenThread String class and functions.
 */

#include "string.hpp"
#include "debug.hpp"

#include <string.h>

namespace ot {

namespace {

// The definitions below are included in an unnamed namespace
// to limit their scope to this translation unit (this file).

enum MatchType : uint8_t
{
    kNoMatch,
    kPrefixMatch,
    kFullMatch,
};

MatchType Match(const char *aString, const char *aPrefixString, StringMatchMode aMode)
{
    // This is file private function that is used by other functions.
    // It matches @p aString with @p aPrefixString using match @ aMode.
    //
    // If @p aString and @p aPrefixString match and have the
    // same length `kFullMatch` is returned. If @p aString starts
    // with @p aPrefixString but contains more characters, then
    // `kPrefixMatch` is returned. Otherwise `kNoMatch` is returned.

    MatchType match = kNoMatch;

    switch (aMode)
    {
    case kStringExactMatch:
        while (*aPrefixString != kNullChar)
        {
            VerifyOrExit(*aString++ == *aPrefixString++);
        }
        break;

    case kStringCaseInsensitiveMatch:
        while (*aPrefixString != kNullChar)
        {
            VerifyOrExit(ToLowercase(*aString++) == ToLowercase(*aPrefixString++));
        }
        break;
    }

    match = (*aString == kNullChar) ? kFullMatch : kPrefixMatch;

exit:
    return match;
}

} // namespace

uint16_t StringLength(const char *aString, uint16_t aMaxLength)
{
    uint16_t ret;

    for (ret = 0; (ret < aMaxLength) && (aString[ret] != kNullChar); ret++)
    {
        // Empty loop.
    }

    return ret;
}

const char *StringFind(const char *aString, char aChar)
{
    const char *ret = nullptr;

    for (; *aString != kNullChar; aString++)
    {
        if (*aString == aChar)
        {
            ret = aString;
            break;
        }
    }

    return ret;
}

const char *StringFind(const char *aString, const char *aSubString, StringMatchMode aMode)
{
    const char *ret    = nullptr;
    size_t      len    = strlen(aString);
    size_t      subLen = strlen(aSubString);

    VerifyOrExit(subLen <= len);

    for (size_t index = 0; index <= static_cast<size_t>(len - subLen); index++)
    {
        if (Match(&aString[index], aSubString, aMode) != kNoMatch)
        {
            ExitNow(ret = &aString[index]);
        }
    }

exit:
    return ret;
}

bool StringStartsWith(const char *aString, const char *aPrefixString, StringMatchMode aMode)
{
    return Match(aString, aPrefixString, aMode) != kNoMatch;
}

bool StringEndsWith(const char *aString, char aChar)
{
    size_t len = strlen(aString);

    return (len > 0) && (aString[len - 1] == aChar);
}

bool StringEndsWith(const char *aString, const char *aSubString, StringMatchMode aMode)
{
    size_t len    = strlen(aString);
    size_t subLen = strlen(aSubString);

    return (subLen > 0) && (len >= subLen) && (Match(&aString[len - subLen], aSubString, aMode) != kNoMatch);
}

bool StringMatch(const char *aFirstString, const char *aSecondString, StringMatchMode aMode)
{
    return Match(aFirstString, aSecondString, aMode) == kFullMatch;
}

void StringConvertToLowercase(char *aString)
{
    for (; *aString != kNullChar; aString++)
    {
        *aString = ToLowercase(*aString);
    }
}

void StringConvertToUppercase(char *aString)
{
    for (; *aString != kNullChar; aString++)
    {
        *aString = ToUppercase(*aString);
    }
}

char ToLowercase(char aChar)
{
    if ((aChar >= 'A') && (aChar <= 'Z'))
    {
        aChar += 'a' - 'A';
    }

    return aChar;
}

char ToUppercase(char aChar)
{
    if ((aChar >= 'a') && (aChar <= 'z'))
    {
        aChar -= 'a' - 'A';
    }

    return aChar;
}

const char *ToYesNo(bool aBool)
{
    static const char *const kYesNoStrings[] = {"no", "yes"};

    return kYesNoStrings[aBool];
}

StringWriter::StringWriter(char *aBuffer, uint16_t aSize)
    : mBuffer(aBuffer)
    , mLength(0)
    , mSize(aSize)
{
    mBuffer[0] = kNullChar;
}

StringWriter &StringWriter::Clear(void)
{
    mBuffer[0] = kNullChar;
    mLength    = 0;
    return *this;
}

StringWriter &StringWriter::Append(const char *aFormat, ...)
{
    va_list args;
    va_start(args, aFormat);
    AppendVarArgs(aFormat, args);
    va_end(args);

    return *this;
}

StringWriter &StringWriter::AppendVarArgs(const char *aFormat, va_list aArgs)
{
    int len;

    len = vsnprintf(mBuffer + mLength, (mSize > mLength ? (mSize - mLength) : 0), aFormat, aArgs);
    OT_ASSERT(len >= 0);

    mLength += static_cast<uint16_t>(len);

    if (IsTruncated())
    {
        mBuffer[mSize - 1] = kNullChar;
    }

    return *this;
}

StringWriter &StringWriter::AppendHexBytes(const uint8_t *aBytes, uint16_t aLength)
{
    while (aLength--)
    {
        Append("%02x", *aBytes++);
    }

    return *this;
}

bool IsValidUtf8String(const char *aString)
{
    return IsValidUtf8String(aString, strlen(aString));
}

bool IsValidUtf8String(const char *aString, size_t aLength)
{
    bool    ret = true;
    uint8_t byte;
    uint8_t continuationBytes = 0;
    size_t  position          = 0;

    while (position < aLength)
    {
        byte = *reinterpret_cast<const uint8_t *>(aString + position);
        ++position;

        if ((byte & 0x80) == 0)
        {
            // We don't allow control characters.
            VerifyOrExit(!iscntrl(byte), ret = false);
            continue;
        }

        // This is a leading byte 1xxx-xxxx.

        if ((byte & 0x40) == 0) // 10xx-xxxx
        {
            // We got a continuation byte pattern without seeing a leading byte earlier.
            ExitNow(ret = false);
        }
        else if ((byte & 0x20) == 0) // 110x-xxxx
        {
            continuationBytes = 1;
        }
        else if ((byte & 0x10) == 0) // 1110-xxxx
        {
            continuationBytes = 2;
        }
        else if ((byte & 0x08) == 0) // 1111-0xxx
        {
            continuationBytes = 3;
        }
        else // 1111-1xxx  (invalid pattern).
        {
            ExitNow(ret = false);
        }

        while (continuationBytes-- != 0)
        {
            VerifyOrExit(position < aLength, ret = false);

            byte = *reinterpret_cast<const uint8_t *>(aString + position);
            ++position;

            // Verify the continuation byte pattern 10xx-xxxx
            VerifyOrExit((byte & 0xc0) == 0x80, ret = false);
        }
    }

exit:
    return ret;
}

} // namespace ot
