/*
 * Copyright (C) 2018, 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_STATS_EVENT_LIST_H
#define ANDROID_STATS_LOG_STATS_EVENT_LIST_H

#include <log/log_event_list.h>
#include <sys/uio.h>

#ifdef __cplusplus
extern "C" {
#endif
void reset_log_context(android_log_context ctx);
int write_to_logger(android_log_context context, log_id_t id);
void note_log_drop(int error, int atom_tag);
void stats_log_close();
int android_log_write_char_array(android_log_context ctx, const char* value, size_t len);
extern int (*write_to_statsd)(struct iovec* vec, size_t nr);

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
/**
 * A copy of android_log_event_list class.
 *
 * android_log_event_list is going to be deprecated soon, so copy it here to
 * avoid creating dependency on upstream code. TODO(b/78304629): Rewrite this
 * code.
 */
class stats_event_list {
  private:
    android_log_context ctx;
    int ret;

    stats_event_list(const stats_event_list&) = delete;
    void operator=(const stats_event_list&) = delete;

  public:
    explicit stats_event_list(int tag) : ret(0) {
        ctx = create_android_logger(static_cast<uint32_t>(tag));
    }
    ~stats_event_list() { android_log_destroy(&ctx); }

    int close() {
        int retval = android_log_destroy(&ctx);
        if (retval < 0) {
            ret = retval;
        }
        return retval;
    }

    /* To allow above C calls to use this class as parameter */
    operator android_log_context() const { return ctx; }

    /* return errors or transmit status */
    int status() const { return ret; }

    int begin() {
        int retval = android_log_write_list_begin(ctx);
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }
    int end() {
        int retval = android_log_write_list_end(ctx);
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }

    stats_event_list& operator<<(int32_t value) {
        int retval = android_log_write_int32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(uint32_t value) {
        int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(bool value) {
        int retval = android_log_write_int32(ctx, value ? 1 : 0);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(int64_t value) {
        int retval = android_log_write_int64(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(uint64_t value) {
        int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(const char* value) {
        int retval = android_log_write_string8(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

#if defined(_USING_LIBCXX)
    stats_event_list& operator<<(const std::string& value) {
        int retval = android_log_write_string8_len(ctx, value.data(), value.length());
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }
#endif

    stats_event_list& operator<<(float value) {
        int retval = android_log_write_float32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    int write(log_id_t id = LOG_ID_EVENTS) {
        /* facilitate -EBUSY retry */
        if ((ret == -EBUSY) || (ret > 0)) {
            ret = 0;
        }
        int retval = write_to_logger(ctx, id);
        /* existing errors trump transmission errors */
        if (!ret) {
            ret = retval;
        }
        return ret;
    }

    /*
     * Append<Type> methods removes any integer promotion
     * confusion, and adds access to string with length.
     * Append methods are also added for all types for
     * convenience.
     */

    bool AppendInt(int32_t value) {
        int retval = android_log_write_int32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendLong(int64_t value) {
        int retval = android_log_write_int64(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendString(const char* value) {
        int retval = android_log_write_string8(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendString(const char* value, size_t len) {
        int retval = android_log_write_string8_len(ctx, value, len);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

#if defined(_USING_LIBCXX)
    bool AppendString(const std::string& value) {
        int retval = android_log_write_string8_len(ctx, value.data(), value.length());
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }

    bool Append(const std::string& value) {
        int retval = android_log_write_string8_len(ctx, value.data(), value.length());
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }
#endif

    bool AppendFloat(float value) {
        int retval = android_log_write_float32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    template <typename Tvalue>
    bool Append(Tvalue value) {
        *this << value;
        return ret >= 0;
    }

    bool Append(const char* value, size_t len) {
        int retval = android_log_write_string8_len(ctx, value, len);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendCharArray(const char* value, size_t len) {
        int retval = android_log_write_char_array(ctx, value, len);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }
};

#endif
#endif  // ANDROID_STATS_LOG_STATS_EVENT_LIST_H
