// Tencent is pleased to support the open source community by making RapidJSON available.
// 
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// 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 "unittest.h"

#include "rapidjson/istreamwrapper.h"
#include "rapidjson/encodedstream.h"
#include "rapidjson/document.h"
#include <sstream>
#include <fstream>

#ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4702) // unreachable code
#endif

using namespace rapidjson;
using namespace std;

template <typename StringStreamType>
static void TestStringStream() {
    typedef typename StringStreamType::char_type Ch;

    {
        StringStreamType iss;
        BasicIStreamWrapper<StringStreamType> is(iss);
        EXPECT_EQ(0, is.Tell());
        if (sizeof(Ch) == 1) {
            EXPECT_EQ(0, is.Peek4());
            EXPECT_EQ(0, is.Tell());
        }
        EXPECT_EQ(0, is.Peek());
        EXPECT_EQ(0, is.Take());
        EXPECT_EQ(0, is.Tell());
    }

    {
        Ch s[] = { 'A', 'B', 'C', '\0' };
        StringStreamType iss(s);
        BasicIStreamWrapper<StringStreamType> is(iss);
        EXPECT_EQ(0, is.Tell());
        if (sizeof(Ch) == 1) {
            EXPECT_EQ(0, is.Peek4()); // less than 4 bytes
        }
        for (int i = 0; i < 3; i++) {
            EXPECT_EQ(static_cast<size_t>(i), is.Tell());
            EXPECT_EQ('A' + i, is.Peek());
            EXPECT_EQ('A' + i, is.Peek());
            EXPECT_EQ('A' + i, is.Take());
        }
        EXPECT_EQ(3, is.Tell());
        EXPECT_EQ(0, is.Peek());
        EXPECT_EQ(0, is.Take());
    }

    {
        Ch s[] = { 'A', 'B', 'C', 'D', 'E', '\0' };
        StringStreamType iss(s);
        BasicIStreamWrapper<StringStreamType> is(iss);
        if (sizeof(Ch) == 1) {
            const Ch* c = is.Peek4();
            for (int i = 0; i < 4; i++)
                EXPECT_EQ('A' + i, c[i]);
            EXPECT_EQ(0, is.Tell());
        }
        for (int i = 0; i < 5; i++) {
            EXPECT_EQ(static_cast<size_t>(i), is.Tell());
            EXPECT_EQ('A' + i, is.Peek());
            EXPECT_EQ('A' + i, is.Peek());
            EXPECT_EQ('A' + i, is.Take());
        }
        EXPECT_EQ(5, is.Tell());
        EXPECT_EQ(0, is.Peek());
        EXPECT_EQ(0, is.Take());
    }
}

TEST(IStreamWrapper, istringstream) {
    TestStringStream<istringstream>();
}

TEST(IStreamWrapper, stringstream) {
    TestStringStream<stringstream>();
}

TEST(IStreamWrapper, wistringstream) {
    TestStringStream<wistringstream>();
}

TEST(IStreamWrapper, wstringstream) {
    TestStringStream<wstringstream>();
}

template <typename FileStreamType>
static bool Open(FileStreamType& fs, const char* filename) {
    const char *paths[] = {
        "encodings",
        "bin/encodings",
        "../bin/encodings",
        "../../bin/encodings",
        "../../../bin/encodings"
    };
    char buffer[1024];
    for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
        sprintf(buffer, "%s/%s", paths[i], filename);
        fs.open(buffer, ios_base::in | ios_base::binary);
        if (fs.is_open())
            return true;
    }
    return false;
}

TEST(IStreamWrapper, ifstream) {
    ifstream ifs;
    ASSERT_TRUE(Open(ifs, "utf8bom.json"));
    IStreamWrapper isw(ifs);
    EncodedInputStream<UTF8<>, IStreamWrapper> eis(isw);
    Document d;
    EXPECT_TRUE(!d.ParseStream(eis).HasParseError());
    EXPECT_TRUE(d.IsObject());
    EXPECT_EQ(5, d.MemberCount());
}

TEST(IStreamWrapper, fstream) {
    fstream fs;
    ASSERT_TRUE(Open(fs, "utf8bom.json"));
    IStreamWrapper isw(fs);
    EncodedInputStream<UTF8<>, IStreamWrapper> eis(isw);
    Document d;
    EXPECT_TRUE(!d.ParseStream(eis).HasParseError());
    EXPECT_TRUE(d.IsObject());
    EXPECT_EQ(5, d.MemberCount());
}

// wifstream/wfstream only works on C++11 with codecvt_utf16
// But many C++11 library still not have it.
#if 0
#include <codecvt>

TEST(IStreamWrapper, wifstream) {
    wifstream ifs;
    ASSERT_TRUE(Open(ifs, "utf16bebom.json"));
    ifs.imbue(std::locale(ifs.getloc(),
       new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
    WIStreamWrapper isw(ifs);
    GenericDocument<UTF16<> > d;
    d.ParseStream<kParseDefaultFlags, UTF16<>, WIStreamWrapper>(isw);
    EXPECT_TRUE(!d.HasParseError());
    EXPECT_TRUE(d.IsObject());
    EXPECT_EQ(5, d.MemberCount());
}

TEST(IStreamWrapper, wfstream) {
    wfstream fs;
    ASSERT_TRUE(Open(fs, "utf16bebom.json"));
    fs.imbue(std::locale(fs.getloc(),
       new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
    WIStreamWrapper isw(fs);
    GenericDocument<UTF16<> > d;
    d.ParseStream<kParseDefaultFlags, UTF16<>, WIStreamWrapper>(isw);
    EXPECT_TRUE(!d.HasParseError());
    EXPECT_TRUE(d.IsObject());
    EXPECT_EQ(5, d.MemberCount());
}

#endif

#ifdef _MSC_VER
RAPIDJSON_DIAG_POP
#endif
