/*
 * 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 "Type.h"
#include <sstream>

#include <hidl-util/StringHelper.h>

namespace android {

Type::Type(std::vector<Qualifier*> *qualifiers)
    : mQualifiers(qualifiers)
    {}

Type::~Type() {
    if(mArrays != NULL) {
        for(auto* array : *mArrays) {
            delete array;
        }
    }

    if(mQualifiers != NULL) {
        for(auto* qual : *mQualifiers) {
            delete qual;
        }
    }
    delete mQualifiers;}


void Type::setArrays(std::vector<Expression*> *arrays) {
    mArrays = arrays;
}

const std::string Type::decorateName(const std::string &name) const {
    std::stringstream ss;

    std::string special = getSpecialTypeName();

    if(special.empty()) {
        ss << getHidlType();
    } else {
        ss << special;
    }

    ss << " " << name;

    return ss.str();
}

// static
std::map<std::string, std::string> Type::kSignedToUnsignedMap = {
    { "char", "uint8_t" },
    { "short", "uint16_t" },
    { "int", "uint32_t" },
    { "long", "uint64_t" },
    { "int8_t", "uint8_t" },
    { "int16_t", "uint16_t" },
    { "int32_t", "uint32_t" },
    { "int64_t", "uint64_t" },
};

// static
const std::string Type::signedToUnsigned(const std::string &signedType) {
    auto it = kSignedToUnsignedMap.find(signedType);

    if (it == kCToHidlMap.end()) {
        return "";
    }

    return (*it).second;
}

// static
std::map<std::string, std::string> Type::kCToHidlMap = {
    { "char", "int8_t /* NOTE: char */" },
    { "short", "int16_t" },
    { "int", "int32_t" },
    { "long", "int64_t"},
    { "native_handle_t", "handle" },
    { "size_t", "uint64_t" },
    { "int8_t", "int8_t" },
    { "uint8_t", "uint8_t" },
    { "int16_t", "int16_t" },
    { "uint16_t", "uint16_t" },
    { "int32_t", "int32_t" },
    { "uint32_t", "uint32_t" },
    { "int64_t", "int64_t" },
    { "uint64_t", "uint64_t" },
    { "float", "float" },
    { "double", "double" },
    { "bool", "bool" },
    { "wchar_t", "int32_t /* NOTE: wchar_t */"},
    // { "hidl_string", "string" },
    // { "hidl_vec", "vec"},
};

// static
const std::string Type::cToHidlType(const std::string &cType) {
    auto it = kCToHidlMap.find(cType);

    if (it == kCToHidlMap.end()) {
        return "";
    }

    return (*it).second;
}

const std::string Type::getHidlType() const {
    if (mQualifiers == NULL) {
        return "";
    }

    std::stringstream ss;

    for (auto it = mQualifiers->begin(); it != mQualifiers->end(); ++it) {
        if (it != mQualifiers->begin()) {
            ss << " ";
        }

        switch((*it)->qualification) {
            case Type::Qualifier::STRUCT:
            case Type::Qualifier::UNION:
            case Type::Qualifier::ENUM:
            case Type::Qualifier::POINTER:
            case Type::Qualifier::CONST: {
                ss << "/* "
                   << Type::qualifierText((*it)->qualification)
                   << " */";
                break;
            }
            case Type::Qualifier::ID: {
                std::string id = (*it)->id;
                std::string conversion = cToHidlType(id);
                if (!conversion.empty()) {
                    ss << conversion;
                } else {
                    std::string baseName = StringHelper::RTrim(id, "_t");
                    ss << StringHelper::ToPascalCase(baseName);
                }
                break;
            }
            case Type::Qualifier::GENERICS: {
                ss << "<"
                   << (*it)->generics->decorateName("")
                   << ">";
                break;
            }
            case Type::Qualifier::UNSIGNED: {
                auto next = it + 1;
                if (next == mQualifiers->end()) {
                    ss << "uint32_t"; // 'unsigned a' -> 'uint32_t a'
                    break;
                }
                std::string unsignedType = signedToUnsigned((*next)->id);
                if(unsignedType.empty()) {
                    ss << Type::qualifierText((*it)->qualification);
                } else {
                    ss << unsignedType;
                    ++it;
                }
                break;
            }
            default: {
                ss << Type::qualifierText((*it)->qualification);
            }
        }
    }

    if (mArrays != NULL) {
        for (const auto &array : *mArrays) {
            ss << "[" << array->toString() << "]";
        }
    }

    return ss.str();
}

const std::string Type::getRawQualifierList() const {
    if (mQualifiers == NULL) {
        return "";
    }

    std::stringstream ss;

    for(auto* qualifier : *mQualifiers) {
        ss << Type::qualifierText(qualifier->qualification) << " ";
    }

    return ss.str();
}

const std::string Type::getSpecialTypeName() const {
    // this makes for a relatively expensive comparison, but it is
    // readable until the converstion get nailed down.
    std::string qualifiers = getRawQualifierList();

    if (qualifiers == "const ID * " ||
        qualifiers == "ID * ") {

        std::string id = mQualifiers->at(mQualifiers->size() - 2)->id;

        if (id == "char") {
            return "string";
        } else {
            // can't tell if it's a hidl_vec or a pointer
            // return "vec<" + id + ">";
            return "";
        }
    }

    return "";
}

bool Type::isVoid() const {
    if (mQualifiers->size() == 0) {
        return true;
    }

    return mQualifiers->size() == 1 &&
           (*mQualifiers)[0]->qualification == Type::Qualifier::VOID;
}

bool Type::isHwDevice() const {
    if (mQualifiers->size() < 2) {
        return false;
    }

    return (*mQualifiers)[0]->qualification == Type::Qualifier::STRUCT &&
        (*mQualifiers)[1]->qualification == Type::Qualifier::ID &&
        (*mQualifiers)[1]->id == "hw_device_t";
}

std::string Type::removeLastId() {
    if(mQualifiers == NULL || mQualifiers->size() == 0) {
        return "";
    }

    Qualifier *last = (*mQualifiers)[mQualifiers->size() - 1];

    if(last == NULL || last->qualification != Qualifier::ID) {
        return "";
    }

    std::string ret{last->id};

    mQualifiers->erase(mQualifiers->end() - 1);

    return ret;
}

} //namespace android
