/*
 * Copyright (C) 2017, 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.
 */

#ifndef ANDROID_STATS_LOG_API_GEN_COLLATION_H
#define ANDROID_STATS_LOG_API_GEN_COLLATION_H


#include <google/protobuf/descriptor.h>

#include <set>
#include <vector>
#include <map>

namespace android {
namespace stats_log_api_gen {

using std::map;
using std::set;
using std::string;
using std::vector;
using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;

const int PULL_ATOM_START_ID = 10000;

const int FIRST_UID_IN_CHAIN_ID = 0;

/**
 * The types for atom parameters.
 */
typedef enum {
  JAVA_TYPE_UNKNOWN = 0,

  JAVA_TYPE_ATTRIBUTION_CHAIN = 1,
  JAVA_TYPE_BOOLEAN = 2,
  JAVA_TYPE_INT = 3,
  JAVA_TYPE_LONG = 4,
  JAVA_TYPE_FLOAT = 5,
  JAVA_TYPE_DOUBLE = 6,
  JAVA_TYPE_STRING = 7,
  JAVA_TYPE_ENUM = 8,
  JAVA_TYPE_KEY_VALUE_PAIR = 9,

  JAVA_TYPE_OBJECT = -1,
  JAVA_TYPE_BYTE_ARRAY = -2,
} java_type_t;

/**
 * The name and type for an atom field.
 */
struct AtomField {
    string name;
    java_type_t javaType;

    // If the field is of type enum, the following map contains the list of enum values.
    map<int /* numeric value */, string /* value name */> enumValues;

    inline AtomField() :name(), javaType(JAVA_TYPE_UNKNOWN) {}
    inline AtomField(const AtomField& that) :name(that.name),
                                             javaType(that.javaType),
                                             enumValues(that.enumValues) {}
    inline AtomField(string n, java_type_t jt) :name(n), javaType(jt) {}
    inline ~AtomField() {}
};

/**
 * The name and code for an atom.
 */
struct AtomDecl {
    int code;
    string name;

    string message;
    vector<AtomField> fields;

    vector<int> primaryFields;
    int exclusiveField = 0;

    int uidField = 0;

    bool whitelisted = false;

    vector<int> binaryFields;

    bool hasModule = false;
    string moduleName;

    AtomDecl();
    AtomDecl(const AtomDecl& that);
    AtomDecl(int code, const string& name, const string& message);
    ~AtomDecl();

    inline bool operator<(const AtomDecl& that) const {
        return (code == that.code) ? (name < that.name) : (code < that.code);
    }
};

struct Atoms {
    map<vector<java_type_t>, set<string>> signatures_to_modules;
    set<AtomDecl> decls;
    set<AtomDecl> non_chained_decls;
    map<vector<java_type_t>, set<string>> non_chained_signatures_to_modules;
    int maxPushedAtomId;
};

/**
 * Gather the information about the atoms.  Returns the number of errors.
 */
int collate_atoms(const Descriptor* descriptor, Atoms* atoms);
int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, vector<java_type_t> *signature);

}  // namespace stats_log_api_gen
}  // namespace android


#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
