/*
 * Copyright (C) 2016 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 "encoder.h"
#include "schema.h"
#include "stream_writer.h"

#include <cstring>

namespace gapic {

Encoder::Encoder(std::shared_ptr<StreamWriter> output) : mOutput(output), mLastObjectId(0) {
    mEntities.insert(std::make_pair(nullptr, 0));
}

void Encoder::Bool(bool v) {
    uint8_t b = v ? 1 : 0;
    mOutput->write(&b, 1);
}

void Encoder::Int8(int8_t v) {
    mOutput->write(&v, 1);
}

void Encoder::Uint8(uint8_t v) {
    mOutput->write(&v, 1);
}

void Encoder::Uint16(uint16_t v) {
    uint8_t buf[9];
    uint16_t space = 0x7f;
    uint8_t tag = 0;
    for (int o = 8; true; o--) {
        if (v <= space) {
            buf[o] = uint8_t(v) | uint8_t(tag);
            mOutput->write(buf + o, 9 - o);
            return;
        }
        buf[o] = uint8_t(v);
        v = v >> 8;
        space >>= 1;
        tag = (tag >> 1) | 0x80;
    }
}

void Encoder::Int16(int16_t v) {
    uint16_t uv = uint16_t(v) << 1;
    Uint16((v < 0) ? ~uv : uv);
}

void Encoder::Float32(float v) {
    uint32_t bits = *reinterpret_cast<uint32_t*>(&v);
    uint32_t shuffled =
            ((bits & 0x000000ff) << 24) |
            ((bits & 0x0000ff00) << 8)  |
            ((bits & 0x00ff0000) >> 8)  |
            ((bits & 0xff000000) >> 24);
    return Uint32(shuffled);
}

void Encoder::Uint32(uint32_t v) {
    uint8_t buf[9];
    uint32_t space = 0x7f;
    uint8_t tag = 0;
    for (int o = 8; true; o--) {
        if (v <= space) {
            buf[o] = uint8_t(v) | uint8_t(tag);
            mOutput->write(buf + o, 9 - o);
            return;
        }
        buf[o] = uint8_t(v);
        v = v >> 8;
        space >>= 1;
        tag = (tag >> 1) | 0x80;
    }
}

void Encoder::Int32(int32_t v) {
    uint32_t uv = uint32_t(v) << 1;
    Uint32((v < 0) ? ~uv : uv);
}

void Encoder::Float64(double v) {
    uint64_t bits = *reinterpret_cast<uint64_t*>(&v);
    uint64_t shuffled =
            ((bits & 0x00000000000000ffULL) << 56) |
            ((bits & 0x000000000000ff00ULL) << 40) |
            ((bits & 0x0000000000ff0000ULL) << 24) |
            ((bits & 0x00000000ff000000ULL) << 8)  |
            ((bits & 0x000000ff00000000ULL) >> 8)  |
            ((bits & 0x0000ff0000000000ULL) >> 24) |
            ((bits & 0x00ff000000000000ULL) >> 40) |
            ((bits & 0xff00000000000000ULL) >> 56);
    return Uint64(shuffled);
}

void Encoder::Uint64(uint64_t v) {
    uint8_t buf[9];
    uint64_t space = 0x7f;
    uint8_t tag = 0;
    for (int o = 8; true; o--) {
        if (v <= space) {
            buf[o] = uint8_t(v) | uint8_t(tag);
            mOutput->write(buf + o, 9 - o);
            return;
        }
        buf[o] = uint8_t(v);
        v = v >> 8;
        space >>= 1;
        tag = (tag >> 1) | 0x80;
    }
}

void Encoder::Int64(int64_t v) {
    uint64_t uv = uint64_t(v) << 1;
    Uint64((v < 0) ? ~uv : uv);
}

void Encoder::Pointer(const void* p) {
    Uint64(reinterpret_cast<uintptr_t>(p));
    Uint32(0); // Pool-id
}

void Encoder::String(const char* v) {
    uint32_t len = v != nullptr ? static_cast<uint32_t>(strlen(v)) : 0;
    Uint32(len);
    mOutput->write(v, len);
}

void Encoder::Data(const void* ptr, int32_t size) {
    mOutput->write(ptr, size);
}

void Encoder::Entity(const schema::Entity* entity) {
    auto ret = mEntities.insert(
        std::make_pair(entity, mEntities.size()));
    uint32_t sid = ret.first->second;
    if (!ret.second) {
        Uint32(sid << 1);
    } else {
        Uint32((sid << 1) | 1);
        entity->encode(*this);
    }
}

void Encoder::Struct(const Encodable& obj) {
    obj.Encode(this);
}

void Encoder::Variant(const Encodable* obj) {
    if (obj == nullptr) {
        Entity(nullptr);
        return;
    }
    Entity(obj->Schema());
    obj->Encode(this);
}

void Encoder::Object(const Encodable* obj) {
    if (obj == nullptr) {
        Uint32(0);
        return;
    }
    uint32_t sid = ++mLastObjectId;
    Uint32((sid << 1) | 1);
    Variant(obj);
}

} // namespace gapic
