// Copyright (C) 2015 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 "base/Win32UnicodeString.h"

#include <algorithm>

#include <windows.h>

#include <string.h>

namespace android {
namespace base {

Win32UnicodeString::Win32UnicodeString() : mStr(nullptr), mSize(0u) {}

Win32UnicodeString::Win32UnicodeString(const char* str, size_t len)
    : mStr(nullptr), mSize(0u) {
    reset(str, strlen(str));
}

Win32UnicodeString::Win32UnicodeString(const char* str)
    : mStr(nullptr), mSize(0u) {
    reset(str);
}

Win32UnicodeString::Win32UnicodeString(const std::string& str)
    : mStr(nullptr), mSize(0u) {
    reset(str.c_str());
}

Win32UnicodeString::Win32UnicodeString(size_t size) : mStr(nullptr), mSize(0u) {
    resize(size);
}

Win32UnicodeString::Win32UnicodeString(const wchar_t* str)
    : mStr(nullptr), mSize(0u) {
    size_t len = str ? wcslen(str) : 0u;
    resize(len);
    ::memcpy(mStr, str ? str : L"", len * sizeof(wchar_t));
}

Win32UnicodeString::Win32UnicodeString(const Win32UnicodeString& other)
    : mStr(nullptr), mSize(0u) {
    resize(other.mSize);
    ::memcpy(mStr, other.c_str(), other.mSize * sizeof(wchar_t));
}

Win32UnicodeString::~Win32UnicodeString() {
    delete[] mStr;
}

Win32UnicodeString& Win32UnicodeString::operator=(
        const Win32UnicodeString& other) {
    resize(other.mSize);
    ::memcpy(mStr, other.c_str(), other.mSize * sizeof(wchar_t));
    return *this;
}

Win32UnicodeString& Win32UnicodeString::operator=(const wchar_t* str) {
    size_t len = str ? wcslen(str) : 0u;
    resize(len);
    ::memcpy(mStr, str ? str : L"", len * sizeof(wchar_t));
    return *this;
}

wchar_t* Win32UnicodeString::data() {
    if (!mStr) {
        // Ensure the function never returns NULL.
        // it is safe to const_cast the pointer here - user isn't allowed to
        // write into it anyway
        return const_cast<wchar_t*>(L"");
    }
    return mStr;
}

std::string Win32UnicodeString::toString() const {
    return convertToUtf8(mStr, mSize);
}

void Win32UnicodeString::reset(const char* str, size_t len) {
    if (mStr) {
        delete[] mStr;
    }
    const int utf16Len = calcUtf16BufferLength(str, len);
    mStr = new wchar_t[utf16Len + 1];
    mSize = static_cast<size_t>(utf16Len);
    convertFromUtf8(mStr, utf16Len, str, len);
    mStr[mSize] = L'\0';
}

void Win32UnicodeString::reset(const char* str) {
    reset(str, strlen(str));
}

void Win32UnicodeString::resize(size_t newSize) {
    if (newSize == 0) {
        delete [] mStr;
        mStr = nullptr;
        mSize = 0;
    } else if (newSize <= mSize) {
        mStr[newSize] = 0;
        mSize = newSize;
    } else {
        wchar_t* oldStr = mStr;
        mStr = new wchar_t[newSize + 1u];
        size_t copySize = std::min<size_t>(newSize, mSize);
        ::memcpy(mStr, oldStr ? oldStr : L"", copySize * sizeof(wchar_t));
        mStr[copySize] = L'\0';
        mStr[newSize] = L'\0';
        mSize = newSize;
        delete[] oldStr;
    }
}

void Win32UnicodeString::append(const wchar_t* str) {
    append(str, wcslen(str));
}

void Win32UnicodeString::append(const wchar_t* str, size_t len) {
    // NOTE: This method should be rarely used, so don't try to optimize
    // storage with larger capacity values and exponential increments.
    if (!str || !len) {
        return;
    }
    size_t oldSize = size();
    resize(oldSize + len);
    memmove(mStr + oldSize, str, len * sizeof(wchar_t));
}

void Win32UnicodeString::append(const Win32UnicodeString& other) {
    append(other.c_str(), other.size());
}

wchar_t* Win32UnicodeString::release() {
    wchar_t* result = mStr;
    mStr = nullptr;
    mSize = 0u;
    return result;
}

// static
std::string Win32UnicodeString::convertToUtf8(const wchar_t* str, int len) {
    std::string result;
    const int utf8Len = calcUtf8BufferLength(str, len);
    if (utf8Len > 0) {
        result.resize(static_cast<size_t>(utf8Len));
        convertToUtf8(&result[0], utf8Len, str, len);
        if (len == -1) {
            result.resize(utf8Len - 1);  // get rid of the null-terminator
        }
    }
    return result;
}

// returns the return value of a Win32UnicodeString public conversion function
// from a WinAPI conversion function returned code
static int convertRetVal(int winapiResult) {
    return winapiResult ? winapiResult : -1;
}

// static
int Win32UnicodeString::calcUtf8BufferLength(const wchar_t* str, int len) {
    if (len < 0 && len != -1) {
        return -1;
    }
    if (len == 0) {
        return 0;
    }
    const int utf8Len = WideCharToMultiByte(CP_UTF8,  // CodePage
                                            0,        // dwFlags
                                            str,      // lpWideCharStr
                                            len,      // cchWideChar
                                            nullptr,  // lpMultiByteStr
                                            0,        // cbMultiByte
                                            nullptr,  // lpDefaultChar
                                            nullptr); // lpUsedDefaultChar

    return convertRetVal(utf8Len);
}

// static
int Win32UnicodeString::calcUtf16BufferLength(const char* str, int len) {
    if (len < 0 && len != -1) {
        return -1;
    }
    if (len == 0) {
        return 0;
    }
    const int utf16Len = MultiByteToWideChar(CP_UTF8,  // CodePage
                                             0,        // dwFlags
                                             str,      // lpMultiByteStr
                                             len,      // cbMultiByte
                                             nullptr,  // lpWideCharStr
                                             0);       // cchWideChar

    return convertRetVal(utf16Len);
}

// static
int Win32UnicodeString::convertToUtf8(char* outStr, int outLen,
                                      const wchar_t* str, int len) {
    if (!outStr || outLen < 0 || !str || (len < 0 && len != -1)) {
        return -1;
    }
    if (len == 0) {
        return 0;
    }

    const int utf8Len = WideCharToMultiByte(CP_UTF8,  // CodePage
                                            0,        // dwFlags
                                            str,      // lpWideCharStr
                                            len,      // cchWideChar
                                            outStr,   // lpMultiByteStr
                                            outLen,   // cbMultiByte
                                            nullptr,  // lpDefaultChar
                                            nullptr); // lpUsedDefaultChar
    return convertRetVal(utf8Len);
}

// static
int Win32UnicodeString::convertFromUtf8(wchar_t* outStr, int outLen,
                                        const char* str, int len) {
    if (!outStr || outLen < 0 || !str || (len < 0 && len != -1)) {
        return -1;
    }
    if (len == 0) {
        return 0;
    }

    const int utf16Len = MultiByteToWideChar(CP_UTF8,  // CodePage
                                             0,        // dwFlags
                                             str,      // lpMultiByteStr
                                             len,      // cbMultiByte
                                             outStr,   // lpWideCharStr
                                             outLen);  // cchWideChar
    return convertRetVal(utf16Len);
}

}  // namespace base
}  // namespace android
