/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <utils/String16.h>

#include <utils/Log.h>
#include <utils/Unicode.h>
#include <utils/String8.h>
#include <utils/threads.h>

#include <memory.h>
#include <stdio.h>
#include <ctype.h>

#include "SharedBuffer.h"

namespace android {

static SharedBuffer* gEmptyStringBuf = NULL;
static char16_t* gEmptyString = NULL;

static inline char16_t* getEmptyString()
{
    gEmptyStringBuf->acquire();
   return gEmptyString;
}

void initialize_string16()
{
    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
    char16_t* str = (char16_t*)buf->data();
    *str = 0;
    gEmptyStringBuf = buf;
    gEmptyString = str;
}

void terminate_string16()
{
    SharedBuffer::bufferFromData(gEmptyString)->release();
    gEmptyStringBuf = NULL;
    gEmptyString = NULL;
}

// ---------------------------------------------------------------------------

static char16_t* allocFromUTF8(const char* u8str, size_t u8len)
{
    if (u8len == 0) return getEmptyString();

    const uint8_t* u8cur = (const uint8_t*) u8str;

    const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);
    if (u16len < 0) {
        return getEmptyString();
    }

    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
    if (buf) {
        u8cur = (const uint8_t*) u8str;
        char16_t* u16str = (char16_t*)buf->data();

        utf8_to_utf16(u8cur, u8len, u16str);

        //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
        //printHexData(1, str, buf->size(), 16, 1);
        //printf("\n");
        
        return u16str;
    }

    return getEmptyString();
}

// ---------------------------------------------------------------------------

String16::String16()
    : mString(getEmptyString())
{
}

String16::String16(StaticLinkage)
    : mString(0)
{
    // this constructor is used when we can't rely on the static-initializers
    // having run. In this case we always allocate an empty string. It's less
    // efficient than using getEmptyString(), but we assume it's uncommon.

    char16_t* data = static_cast<char16_t*>(
            SharedBuffer::alloc(sizeof(char16_t))->data());
    data[0] = 0;
    mString = data;
}

String16::String16(const String16& o)
    : mString(o.mString)
{
    SharedBuffer::bufferFromData(mString)->acquire();
}

String16::String16(const String16& o, size_t len, size_t begin)
    : mString(getEmptyString())
{
    setTo(o, len, begin);
}

String16::String16(const char16_t* o)
{
    size_t len = strlen16(o);
    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
    ALOG_ASSERT(buf, "Unable to allocate shared buffer");
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        strcpy16(str, o);
        mString = str;
        return;
    }
    
    mString = getEmptyString();
}

String16::String16(const char16_t* o, size_t len)
{
    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
    ALOG_ASSERT(buf, "Unable to allocate shared buffer");
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        memcpy(str, o, len*sizeof(char16_t));
        str[len] = 0;
        mString = str;
        return;
    }
    
    mString = getEmptyString();
}

String16::String16(const String8& o)
    : mString(allocFromUTF8(o.string(), o.size()))
{
}

String16::String16(const char* o)
    : mString(allocFromUTF8(o, strlen(o)))
{
}

String16::String16(const char* o, size_t len)
    : mString(allocFromUTF8(o, len))
{
}

String16::~String16()
{
    SharedBuffer::bufferFromData(mString)->release();
}

size_t String16::size() const
{
    return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1;
}

void String16::setTo(const String16& other)
{
    SharedBuffer::bufferFromData(other.mString)->acquire();
    SharedBuffer::bufferFromData(mString)->release();
    mString = other.mString;
}

status_t String16::setTo(const String16& other, size_t len, size_t begin)
{
    const size_t N = other.size();
    if (begin >= N) {
        SharedBuffer::bufferFromData(mString)->release();
        mString = getEmptyString();
        return NO_ERROR;
    }
    if ((begin+len) > N) len = N-begin;
    if (begin == 0 && len == N) {
        setTo(other);
        return NO_ERROR;
    }

    if (&other == this) {
        LOG_ALWAYS_FATAL("Not implemented");
    }

    return setTo(other.string()+begin, len);
}

status_t String16::setTo(const char16_t* other)
{
    return setTo(other, strlen16(other));
}

status_t String16::setTo(const char16_t* other, size_t len)
{
    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
        ->editResize((len+1)*sizeof(char16_t));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        memmove(str, other, len*sizeof(char16_t));
        str[len] = 0;
        mString = str;
        return NO_ERROR;
    }
    return NO_MEMORY;
}

status_t String16::append(const String16& other)
{
    const size_t myLen = size();
    const size_t otherLen = other.size();
    if (myLen == 0) {
        setTo(other);
        return NO_ERROR;
    } else if (otherLen == 0) {
        return NO_ERROR;
    }
    
    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
        mString = str;
        return NO_ERROR;
    }
    return NO_MEMORY;
}

status_t String16::append(const char16_t* chrs, size_t otherLen)
{
    const size_t myLen = size();
    if (myLen == 0) {
        setTo(chrs, otherLen);
        return NO_ERROR;
    } else if (otherLen == 0) {
        return NO_ERROR;
    }
    
    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
        str[myLen+otherLen] = 0;
        mString = str;
        return NO_ERROR;
    }
    return NO_MEMORY;
}

status_t String16::insert(size_t pos, const char16_t* chrs)
{
    return insert(pos, chrs, strlen16(chrs));
}

status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
{
    const size_t myLen = size();
    if (myLen == 0) {
        return setTo(chrs, len);
        return NO_ERROR;
    } else if (len == 0) {
        return NO_ERROR;
    }

    if (pos > myLen) pos = myLen;

    #if 0
    printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
           String8(*this).string(), pos,
           len, myLen, String8(chrs, len).string());
    #endif

    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
        ->editResize((myLen+len+1)*sizeof(char16_t));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        if (pos < myLen) {
            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
        }
        memcpy(str+pos, chrs, len*sizeof(char16_t));
        str[myLen+len] = 0;
        mString = str;
        #if 0
        printf("Result (%d chrs): %s\n", size(), String8(*this).string());
        #endif
        return NO_ERROR;
    }
    return NO_MEMORY;
}

ssize_t String16::findFirst(char16_t c) const
{
    const char16_t* str = string();
    const char16_t* p = str;
    const char16_t* e = p + size();
    while (p < e) {
        if (*p == c) {
            return p-str;
        }
        p++;
    }
    return -1;
}

ssize_t String16::findLast(char16_t c) const
{
    const char16_t* str = string();
    const char16_t* p = str;
    const char16_t* e = p + size();
    while (p < e) {
        e--;
        if (*e == c) {
            return e-str;
        }
    }
    return -1;
}

bool String16::startsWith(const String16& prefix) const
{
    const size_t ps = prefix.size();
    if (ps > size()) return false;
    return strzcmp16(mString, ps, prefix.string(), ps) == 0;
}

bool String16::startsWith(const char16_t* prefix) const
{
    const size_t ps = strlen16(prefix);
    if (ps > size()) return false;
    return strncmp16(mString, prefix, ps) == 0;
}

bool String16::contains(const char16_t* chrs) const
{
    return strstr16(mString, chrs) != nullptr;
}

status_t String16::makeLower()
{
    const size_t N = size();
    const char16_t* str = string();
    char16_t* edit = NULL;
    for (size_t i=0; i<N; i++) {
        const char16_t v = str[i];
        if (v >= 'A' && v <= 'Z') {
            if (!edit) {
                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
                if (!buf) {
                    return NO_MEMORY;
                }
                edit = (char16_t*)buf->data();
                mString = str = edit;
            }
            edit[i] = tolower((char)v);
        }
    }
    return NO_ERROR;
}

status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
{
    const size_t N = size();
    const char16_t* str = string();
    char16_t* edit = NULL;
    for (size_t i=0; i<N; i++) {
        if (str[i] == replaceThis) {
            if (!edit) {
                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
                if (!buf) {
                    return NO_MEMORY;
                }
                edit = (char16_t*)buf->data();
                mString = str = edit;
            }
            edit[i] = withThis;
        }
    }
    return NO_ERROR;
}

status_t String16::remove(size_t len, size_t begin)
{
    const size_t N = size();
    if (begin >= N) {
        SharedBuffer::bufferFromData(mString)->release();
        mString = getEmptyString();
        return NO_ERROR;
    }
    if ((begin+len) > N) len = N-begin;
    if (begin == 0 && len == N) {
        return NO_ERROR;
    }

    if (begin > 0) {
        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
            ->editResize((N+1)*sizeof(char16_t));
        if (!buf) {
            return NO_MEMORY;
        }
        char16_t* str = (char16_t*)buf->data();
        memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
        mString = str;
    }
    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
        ->editResize((len+1)*sizeof(char16_t));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        str[len] = 0;
        mString = str;
        return NO_ERROR;
    }
    return NO_MEMORY;
}

}; // namespace android
