// 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 <ctime>
#include <fstream>

#include "generator.h"

using std::ofstream;
using std::string;

static constexpr char kAuthors[] = "The Fuchsia Authors";
static constexpr char kWrapMacro[] = "ZX_SYSCALL_PARAM_ATTR";
static constexpr char kDefaultHandleAnnotation[] = "handle_use";
bool is_identifier_keyword(const string& iden);

bool Generator::header(ofstream& os) {
    auto t = std::time(nullptr);
    auto ltime = std::localtime(&t);

    os << "// Copyright " << ltime->tm_year + 1900
       << " " << kAuthors << ". All rights reserved.\n";
    os << "// This is a GENERATED file, see //zircon/system/host/abigen.\n";
    os << "// The license governing this file can be found in the LICENSE file.\n\n";

    return os.good();
}

bool Generator::footer(ofstream& os) {
    os << "\n";
    return os.good();
}

bool VDsoAsmGenerator::syscall(ofstream& os, const Syscall& sc) {
    if (!sc.is_vdso()) {
        bool is_public = !sc.is_internal();
        for (const CallWrapper* wrapper : wrappers_) {
            if (wrapper->applies(sc)) {
                is_public = false;
                break;
            }
        }

        // m_syscall name, syscall_num, nargs
        os << syscall_macro_
           << " " << name_prefix_ << sc.name
           << " " << sc.index
           << " " << sc.num_kernel_args()
           << " " << (is_public ? 1 : 0)
           << "\n";
    }
    return os.good();
}

bool KernelBranchGenerator::header(ofstream& os) {
    if (!Generator::header(os))
        return false;

    os << "start_syscall_dispatch\n";
    return os.good();
}

bool KernelBranchGenerator::syscall(ofstream& os, const Syscall& sc) {
    if (sc.is_vdso()) {
        return os.good();
    }
    os << "syscall_dispatch " << sc.num_kernel_args() << " " << sc.name << "\n";
    return os.good();
}

bool SyscallNumbersGenerator::syscall(ofstream& os, const Syscall& sc) {
    if (sc.is_vdso())
        return true;

    num_calls_++;
    os << define_prefix_ << sc.name << " " << sc.index << "\n";
    return os.good();
}

bool SyscallNumbersGenerator::footer(ofstream& os) {
    os << define_prefix_ << "COUNT " << num_calls_ << "\n";
    return os.good();
}

bool TraceInfoGenerator::syscall(ofstream& os, const Syscall& sc) {
    if (sc.is_vdso())
        return true;

    // Can be injected as an array of structs or into a tuple-like C++ container.
    os << "{" << sc.index << ", " << sc.num_kernel_args() << ", "
       << '"' << sc.name << "\"},\n";

    return os.good();
}

bool CategoryGenerator::syscall(ofstream& os, const Syscall& sc) {
    for (const auto& attr : sc.attributes) {
        if (attr != "*" && attr != "internal")
            category_map_[attr].push_back(&sc.name);
    }
    return true;
}

bool CategoryGenerator::footer(ofstream& os) {
    for (const auto& category : category_map_) {
        os << "\n#define HAVE_SYSCALL_CATEGORY_" << category.first << " 1\n";
        os << "SYSCALL_CATEGORY_BEGIN(" << category.first << ")\n";

        for (auto sc : category.second)
            os << "    SYSCALL_IN_CATEGORY(" << *sc << ")\n";

        os << "SYSCALL_CATEGORY_END(" << category.first << ")\n";
    }
    return os.good();
}

void write_syscall_signature_line(ofstream& os, const Syscall& sc, string name_prefix,
                                  string before_args, string inter_arg,
                                  bool wrap_pointers_with_user_ptr, string no_args_type) {
    auto syscall_name = name_prefix + sc.name;

    // writes "[return-type] prefix_[syscall-name]("
    os << sc.return_type() << " " << syscall_name << "(";

    // Writes all arguments.
    os << before_args;
    bool first = true;
    sc.for_each_kernel_arg([&](const TypeSpec& arg) {
        if (!first) {
            os << inter_arg;
        }
        first = false;
        write_argument_annotation(os, arg);
        os << arg.as_cpp_declaration(wrap_pointers_with_user_ptr) << ",";
    });

    if (sc.num_kernel_args() > 0) {
        // remove the comma.
        os.seekp(-1, std::ios_base::end);
    } else {
        os << no_args_type;
    }

    os << ")";
}

string write_syscall_return_var(ofstream& os, const Syscall& sc) {
    string return_var = sc.is_void_return() ? "" : "ret";
    if (!sc.is_void_return()) {
        os << sc.return_type() << " " << return_var << ";\n";
    }
    return return_var;
}

void write_syscall_invocation(ofstream& os, const Syscall& sc,
                              const string& return_var, const string& name_prefix) {
    if (!return_var.empty()) {
        os << return_var << " = ";
    }

    os << name_prefix << sc.name << "(";

    // Writes all arguments.
    sc.for_each_kernel_arg([&](const TypeSpec& arg) {
        os << arg.name << ", ";
    });

    if (sc.num_kernel_args() > 0) {
        // remove the comma and space.
        os.seekp(-2, std::ios_base::end);
    }

    os << ");\n";
}

void write_argument_annotation(std::ofstream& os, const TypeSpec& arg) {
    bool has_annotation = false;
    for (const auto& a : arg.attributes) {
        if (!a.empty() && !is_identifier_keyword(a)) {
            has_annotation = true;
            os << kWrapMacro << "(" << a << ") ";
        }
    }
    // If arg type is a handle (not an array) and no annotation is present, use default annotation
    if (!has_annotation && arg.type == "zx_handle_t" && arg.arr_spec == nullptr) {
        os << kWrapMacro << "(" << kDefaultHandleAnnotation << ") ";
    }
}
