// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>

#include "types.h"

using std::string;
using std::vector;

const std::map<string, string> rust_overrides = {
    {"any[]IN", "*const u8"},
    {"any[]OUT", "*mut u8"},
    {"any[]INOUT", "*mut u8"}};

const std::map<string, string> rust_primitives = {
    {"int8_t", "i8"},
    {"int16_t", "i16"},
    {"int32_t", "i32"},
    {"int64_t", "i64"},
    {"uint8_t", "u8"},
    {"uint16_t", "u16"},
    {"uint32_t", "u32"},
    {"uint64_t", "u64"},
    {"size_t", "usize"},
    {"uintptr_t", "usize"},
    {"int", "isize"},
    {"char", "u8"},
    {"float", "f32"},
    {"double", "f64"},
};

const std::map<string, string> rust_reserved_words = {
    {"proc", "proc_"},
};

bool has_attribute(const char* attr, const vector<string>& attrs) {
    return std::find(attrs.begin(), attrs.end(), attr) != attrs.end();
}

void dump_attributes(const vector<string>& attrs) {
    for (auto& a : attrs) {
        fprintf(stderr, "%s ", a.c_str());
    }
    fprintf(stderr, "\n");
}

string ArraySpec::kind_str() const {
    switch (kind) {
    case IN:
        return "IN";
    case OUT:
        return "OUT";
    default:
        return "INOUT";
    }
}

string ArraySpec::kind_lowercase_str() const {
    switch (kind) {
    case IN:
        return "in";
    case OUT:
        return "out";
    default:
        return "inout";
    }
}

bool ArraySpec::assign_kind(const vector<string>& attrs) {
    if (has_attribute("IN", attrs)) {
        kind = ArraySpec::IN;
    } else if (has_attribute("OUT", attrs)) {
        kind = ArraySpec::OUT;
    } else if (has_attribute("INOUT", attrs)) {
        kind = ArraySpec::INOUT;
    } else {
        return false;
    }
    return true;
}

string ArraySpec::to_string() const {
    return "[]" + kind_str();
}

const string map_override(const string& name, const std::map<string, string>& overrides) {
    auto ft = overrides.find(name);
    return (ft == overrides.end()) ? name : ft->second;
}

string TypeSpec::to_string() const {
    return type + (arr_spec ? arr_spec->to_string() : string());
}

string TypeSpec::as_cpp_declaration(bool is_wrapped) const {
    if (!arr_spec) {
        return type + " " + name;
    }

    if (is_wrapped &&
        arr_spec->kind == ArraySpec::OUT && arr_spec->count == 1 &&
        type == "zx_handle_t") {
        return "user_out_handle* " + name;
    }

    string modifier = arr_spec->kind == ArraySpec::IN ? "const " : "";
    string ptr_type = type == "any" ? "void" : type;

    if (is_wrapped) {
        // This policy strings here matches the enum defined in the
        // kernel's user_ptr.h.
        string policy = arr_spec->kind_lowercase_str();
        return "user_" + policy + "_ptr<" + modifier + ptr_type + "> " + name;
    }
    return modifier + ptr_type + "* " + name;
}

string TypeSpec::as_rust_declaration() const {
    auto overridden = map_override(to_string(), rust_overrides);
    auto scalar_type = map_override(type, rust_primitives);
    auto safe_name = map_override(name, rust_reserved_words);

    if (overridden != to_string()) {
        return safe_name + ": " + overridden;
    } else if (!arr_spec) {
        return safe_name + ": " + scalar_type;
    } else {
        string ret = safe_name + ": ";
        if (arr_spec->kind == ArraySpec::IN) {
            ret += "*const ";
        } else {
            ret += "*mut ";
        }

        ret += scalar_type;
        if (arr_spec->count > 1)
            ret += " " + std::to_string(arr_spec->count);
        return ret;
    }
}

string TypeSpec::as_cpp_cast(const string& arg) const {
    if (!arr_spec) {
        return "static_cast<" + type + ">(" + arg + ")";
    }

    string modifier = arr_spec->kind == ArraySpec::IN ? "const " : "";
    string cast_type = type == "any" ? "void*" : type + "*";
    return "reinterpret_cast<" + modifier + cast_type + ">(" + arg + ")";
}

bool Syscall::is_vdso() const {
    return has_attribute("vdsocall", attributes);
}

bool Syscall::is_noreturn() const {
    return has_attribute("noreturn", attributes);
}

bool Syscall::is_blocking() const {
    return has_attribute("blocking", attributes);
}

bool Syscall::is_internal() const {
    return has_attribute("internal", attributes);
}

size_t Syscall::num_kernel_args() const {
    if (is_noreturn()) {
        return arg_spec.size();
    }

    // The first return value is passed as the ordinary C return
    // value, but only if there is at least one return value.
    size_t ret_values = ret_spec.size();
    if (ret_values > 0) {
        --ret_values;
    }
    return arg_spec.size() + ret_values;
}

void Syscall::for_each_return(const std::function<void(const TypeSpec&)>& cb) const {
    if (ret_spec.size() > 1) {
        std::for_each(ret_spec.begin() + 1, ret_spec.end(), cb);
    }
}

void Syscall::for_each_kernel_arg(const std::function<void(const TypeSpec&)>& cb) const {
    std::for_each(arg_spec.begin(), arg_spec.end(), cb);
    for_each_return(cb);
}

bool Syscall::validate() const {
    if (ret_spec.size() > 0 && is_noreturn()) {
        print_error("noreturn should have zero return arguments");
        return false;
    }

    if (num_kernel_args() > kMaxArgs) {
        print_error("invalid number of arguments");
        return false;
    }

    if (ret_spec.size() >= 1 && !ret_spec[0].name.empty()) {
        print_error("the first return argument cannot be named, yet...");
        return false;
    }

    if (is_blocking() &&
        (ret_spec.size() == 0 || ret_spec[0].type != "zx_status_t")) {
        print_error("blocking must have first return be of type zx_status_t");
        return false;
    }

    if (is_vdso() && is_internal()) {
        print_error("vdsocall cannot be internal");
        return false;
    }

    bool valid_args = true;
    for_each_kernel_arg([this, &valid_args](const TypeSpec& arg) {
        if (arg.name.empty()) {
            print_error("all arguments need to be named, except the first return");
            valid_args = false;
        }
        if (arg.arr_spec) {
            if (!validate_array_spec(arg)) {
                valid_args = false;
            }
        }
    });
    return valid_args;
}

void Syscall::assign_index(int* next_index) {
    if (!is_vdso())
        index = (*next_index)++;
}

bool Syscall::validate_array_spec(const TypeSpec& ts) const {
    if (ts.arr_spec->count > 0)
        return true;
    // find arguments that represent the array count.
    for (const string& multiplier : ts.arr_spec->multipliers) {
        auto arg = std::find_if(arg_spec.begin(), arg_spec.end(), [&](const TypeSpec& a) {
            return a.name == multiplier;
        });
        if (arg == arg_spec.end()) {
            std::string err = "invalid array spec for " + ts.name + ": '" + multiplier + "' does not refer to an argument";
            print_error(err.c_str());
            return false;
        }
        // TODO:cpu also enforce INOUT here.
        if (arg->arr_spec && arg->arr_spec->count != 1u) {
            std::string err = "invalid array spec for " + ts.name + ": '" + multiplier + "' refers to an array of size != 1";
            return false;
        }
    }
    return true;
}

void Syscall::print_error(const char* what) const {
    fprintf(stderr, "error: %s  : %s\n", name.c_str(), what);
}

string Syscall::return_type() const {
    if (ret_spec.empty()) {
        return "void";
    }
    return ret_spec[0].to_string();
}

bool Syscall::is_void_return() const {
    return return_type() == "void";
}
