#include "Errors.h"

#include "string_utils.h"

#include "google/protobuf/compiler/plugin.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "google/protobuf/text_format.h"

#include <stdio.h>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <map>

using namespace android::javastream_proto;
using namespace google::protobuf;
using namespace google::protobuf::compiler;
using namespace google::protobuf::io;
using namespace std;

const int FIELD_TYPE_SHIFT = 32;
const uint64_t FIELD_TYPE_DOUBLE = 1L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_FLOAT = 2L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_INT32 = 3L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_INT64 = 4L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_UINT32 = 5L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_UINT64 = 6L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_SINT32 = 7L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_SINT64 = 8L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_FIXED32 = 9L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_FIXED64 = 10L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_SFIXED32 = 11L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_SFIXED64 = 12L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_BOOL = 13L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_STRING = 14L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_BYTES = 15L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_ENUM = 16L << FIELD_TYPE_SHIFT;
const uint64_t FIELD_TYPE_OBJECT = 17L << FIELD_TYPE_SHIFT;

const int FIELD_COUNT_SHIFT = 40;
const uint64_t FIELD_COUNT_SINGLE = 1L << FIELD_COUNT_SHIFT;
const uint64_t FIELD_COUNT_REPEATED = 2L << FIELD_COUNT_SHIFT;
const uint64_t FIELD_COUNT_PACKED = 5L << FIELD_COUNT_SHIFT;


/**
 * See if this is the file for this request, and not one of the imported ones.
 */
static bool
should_generate_for_file(const CodeGeneratorRequest& request, const string& file)
{
    const int N = request.file_to_generate_size();
    for (int i=0; i<N; i++) {
        if (request.file_to_generate(i) == file) {
            return true;
        }
    }
    return false;
}

/**
 * If the descriptor gives us a class name, use that. Otherwise make one up from
 * the filename of the .proto file.
 */
static string
make_outer_class_name(const FileDescriptorProto& file_descriptor)
{
    string name = file_descriptor.options().java_outer_classname();
    if (name.size() == 0) {
        name = to_camel_case(file_base_name(file_descriptor.name()));
        if (name.size() == 0) {
            ERRORS.Add(UNKNOWN_FILE, UNKNOWN_LINE,
                    "Unable to make an outer class name for file: %s",
                    file_descriptor.name().c_str());
            name = "Unknown";
        }
    }
    return name;
}

/**
 * Figure out the package name that we are generating.
 */
static string
make_java_package(const FileDescriptorProto& file_descriptor) {
    if (file_descriptor.options().has_java_package()) {
        return file_descriptor.options().java_package();
    } else {
        return file_descriptor.package();
    }
}

/**
 * Figure out the name of the file we are generating.
 */
static string
make_file_name(const FileDescriptorProto& file_descriptor)
{
    string const package = make_java_package(file_descriptor);
    string result;
    if (package.size() > 0) {
        result = replace_string(package, '.', '/');
        result += '/';
    }

    result += make_outer_class_name(file_descriptor);
    result += ".java";

    return result;
}

static string
indent_more(const string& indent)
{
    return indent + "    ";
}

/**
 * Write the constants for an enum.
 */
static void
write_enum(stringstream& text, const EnumDescriptorProto& enu, const string& indent)
{
    const int N = enu.value_size();
    text << indent << "// enum " << enu.name() << endl;
    for (int i=0; i<N; i++) {
        const EnumValueDescriptorProto& value = enu.value(i);
        text << indent << "public static final int "
                << make_constant_name(value.name())
                << " = " << value.number() << ";" << endl;
    }
    text << endl;
}

/**
 * Get the string name for a field.
 */
static string
get_proto_type(const FieldDescriptorProto& field)
{
    switch (field.type()) {
        case FieldDescriptorProto::TYPE_DOUBLE:
            return "double";
        case FieldDescriptorProto::TYPE_FLOAT:
            return "float";
        case FieldDescriptorProto::TYPE_INT64:
            return "int64";
        case FieldDescriptorProto::TYPE_UINT64:
            return "uint64";
        case FieldDescriptorProto::TYPE_INT32:
            return "int32";
        case FieldDescriptorProto::TYPE_FIXED64:
            return "fixed64";
        case FieldDescriptorProto::TYPE_FIXED32:
            return "fixed32";
        case FieldDescriptorProto::TYPE_BOOL:
            return "bool";
        case FieldDescriptorProto::TYPE_STRING:
            return "string";
        case FieldDescriptorProto::TYPE_GROUP:
            return "group<unsupported!>";
        case FieldDescriptorProto::TYPE_MESSAGE:
            return field.type_name();
        case FieldDescriptorProto::TYPE_BYTES:
            return "bytes";
        case FieldDescriptorProto::TYPE_UINT32:
            return "uint32";
        case FieldDescriptorProto::TYPE_ENUM:
            return field.type_name();
        case FieldDescriptorProto::TYPE_SFIXED32:
            return "sfixed32";
        case FieldDescriptorProto::TYPE_SFIXED64:
            return "sfixed64";
        case FieldDescriptorProto::TYPE_SINT32:
            return "sint32";
        case FieldDescriptorProto::TYPE_SINT64:
            return "sint64";
        default:
            // won't happen
            return "void";
    }
}

static uint64_t
get_field_id(const FieldDescriptorProto& field)
{
    // Number
    uint64_t result = (uint32_t)field.number();

    // Type
    switch (field.type()) {
        case FieldDescriptorProto::TYPE_DOUBLE:
            result |= FIELD_TYPE_DOUBLE;
        case FieldDescriptorProto::TYPE_FLOAT:
            result |= FIELD_TYPE_FLOAT;
        case FieldDescriptorProto::TYPE_INT64:
            result |= FIELD_TYPE_INT64;
        case FieldDescriptorProto::TYPE_UINT64:
            result |= FIELD_TYPE_UINT64;
        case FieldDescriptorProto::TYPE_INT32:
            result |= FIELD_TYPE_INT32;
        case FieldDescriptorProto::TYPE_FIXED64:
            result |= FIELD_TYPE_FIXED64;
        case FieldDescriptorProto::TYPE_FIXED32:
            result |= FIELD_TYPE_FIXED32;
        case FieldDescriptorProto::TYPE_BOOL:
            result |= FIELD_TYPE_BOOL;
        case FieldDescriptorProto::TYPE_STRING:
            result |= FIELD_TYPE_STRING;
        case FieldDescriptorProto::TYPE_MESSAGE:
            result |= FIELD_TYPE_OBJECT;
        case FieldDescriptorProto::TYPE_BYTES:
            result |= FIELD_TYPE_BYTES;
        case FieldDescriptorProto::TYPE_UINT32:
            result |= FIELD_TYPE_UINT32;
        case FieldDescriptorProto::TYPE_ENUM:
            result |= FIELD_TYPE_ENUM;
        case FieldDescriptorProto::TYPE_SFIXED32:
            result |= FIELD_TYPE_SFIXED32;
        case FieldDescriptorProto::TYPE_SFIXED64:
            result |= FIELD_TYPE_SFIXED64;
        case FieldDescriptorProto::TYPE_SINT32:
            result |= FIELD_TYPE_SINT32;
        case FieldDescriptorProto::TYPE_SINT64:
            result |= FIELD_TYPE_SINT64;
        default:
            ;
    }

    // Count
    if (field.options().packed()) {
        result |= FIELD_COUNT_PACKED;
    } else if (field.label() == FieldDescriptorProto::LABEL_REPEATED) {
        result |= FIELD_COUNT_REPEATED;
    } else {
        result |= FIELD_COUNT_SINGLE;
    }

    return result;
}

/**
 * Write a field.
 */
static void
write_field(stringstream& text, const FieldDescriptorProto& field, const string& indent)
{
    string optional_comment = field.label() == FieldDescriptorProto::LABEL_OPTIONAL
            ? "optional " : "";
    string repeated_comment = field.label() == FieldDescriptorProto::LABEL_REPEATED
            ? "repeated " : "";
    string proto_type = get_proto_type(field);
    string packed_comment = field.options().packed()
            ? " [packed=true]" : "";
    text << indent << "// " << optional_comment << repeated_comment << proto_type << ' '
            << field.name() << " = " << field.number() << packed_comment << ';' << endl;

    text << indent << "public static final long " << make_constant_name(field.name()) << " = 0x";

    ios::fmtflags fmt(text.flags());
    text << setfill('0') << setw(16) << hex << get_field_id(field);
    text.flags(fmt);

    text << "L;" << endl;

    text << endl;
}

/**
 * Write a Message constants class.
 */
static void
write_message(stringstream& text, const DescriptorProto& message, const string& indent)
{
    int N;
    const string indented = indent_more(indent);

    text << indent << "// message " << message.name() << endl;
    text << indent << "public final class " << message.name() << " {" << endl;
    text << endl;

    // Enums
    N = message.enum_type_size();
    for (int i=0; i<N; i++) {
        write_enum(text, message.enum_type(i), indented);
    }

    // Nested classes
    N = message.nested_type_size();
    for (int i=0; i<N; i++) {
        write_message(text, message.nested_type(i), indented);
    }

    // Fields
    N = message.field_size();
    for (int i=0; i<N; i++) {
        write_field(text, message.field(i), indented);
    }

    text << indent << "}" << endl;
    text << endl;
}

/**
 * Write the contents of a file.
 */
static void
write_file(stringstream& text, const FileDescriptorProto& file_descriptor)
{
    string const package_name = make_java_package(file_descriptor);
    string const outer_class_name = make_outer_class_name(file_descriptor);

    text << "// Generated by protoc-gen-javastream. DO NOT MODIFY." << endl;
    text << "// source: " << file_descriptor.name() << endl << endl;

    if (package_name.size() > 0) {
        if (package_name.size() > 0) {
            text << "package " << package_name << ";" << endl;
            text << endl;
        }
    }

    // This bit of policy is android api rules specific: Raw proto classes
    // must never be in the API, but they should all be available for testing.
    text << "/** @hide */" << endl;
    text << "@android.annotation.TestApi" << endl;

    text << "public final class " << outer_class_name << " {" << endl;
    text << endl;

    int N;
    const string indented = indent_more("");
    
    N = file_descriptor.enum_type_size();
    for (int i=0; i<N; i++) {
        write_enum(text, file_descriptor.enum_type(i), indented);
    }

    N = file_descriptor.message_type_size();
    for (int i=0; i<N; i++) {
        write_message(text, file_descriptor.message_type(i), indented);
    }

    text << "}" << endl;
}

/**
 * Main.
 */
int
main(int argc, char const*const* argv)
{
    (void)argc;
    (void)argv;

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    CodeGeneratorRequest request;
    CodeGeneratorResponse response;

    // Read the request
    request.ParseFromIstream(&cin);

    // Build the files we need.
    const int N = request.proto_file_size();
    for (int i=0; i<N; i++) {
        const FileDescriptorProto& file_descriptor = request.proto_file(i);
        if (should_generate_for_file(request, file_descriptor.name())) {
            // Generate the text
            stringstream text;
            write_file(text, file_descriptor);

            // Put the text in the response
            CodeGeneratorResponse::File* file_response = response.add_file();
            file_response->set_name(make_file_name(file_descriptor));
            file_response->set_content(text.str());

            cerr << "writing file: " << file_response->name() << endl;
        }
    }

    // If we had errors, don't write the response. Print the errors and exit.
    if (ERRORS.HasErrors()) {
        ERRORS.Print();
        return 1;
    }

    // If we didn't have errors, write the response and exit happily.
    response.SerializeToOstream(&cout);
    return 0;
}
