/*
 * 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.
 */
package android.os;

import android.util.Slog;

import java.util.ArrayList;
import java.util.List;

/**
 * Wrapper class for sending data from Android OS to StatsD.
 *
 * @hide
 */
public final class StatsLogEventWrapper implements Parcelable {
    static final boolean DEBUG = false;
    static final String TAG = "StatsLogEventWrapper";

    // Keep in sync with FieldValue.h enums
    private static final int EVENT_TYPE_UNKNOWN = 0;
    private static final int EVENT_TYPE_INT = 1; /* int32_t */
    private static final int EVENT_TYPE_LONG = 2; /* int64_t */
    private static final int EVENT_TYPE_FLOAT = 3;
    private static final int EVENT_TYPE_DOUBLE = 4;
    private static final int EVENT_TYPE_STRING = 5;
    private static final int EVENT_TYPE_STORAGE = 6;

    List<Integer> mTypes = new ArrayList<>();
    List<Object> mValues = new ArrayList<>();
    int mTag;
    long mElapsedTimeNs;
    long mWallClockTimeNs;
    WorkSource mWorkSource = null;

    public StatsLogEventWrapper(int tag, long elapsedTimeNs, long wallClockTimeNs) {
        this.mTag = tag;
        this.mElapsedTimeNs = elapsedTimeNs;
        this.mWallClockTimeNs = wallClockTimeNs;
    }

    /**
     * Boilerplate for Parcel.
     */
    public static final @android.annotation.NonNull Parcelable.Creator<StatsLogEventWrapper> CREATOR = new
            Parcelable.Creator<StatsLogEventWrapper>() {
                public StatsLogEventWrapper createFromParcel(Parcel in) {
                    return new StatsLogEventWrapper(in);
                }

                public StatsLogEventWrapper[] newArray(int size) {
                    return new StatsLogEventWrapper[size];
                }
            };

    private StatsLogEventWrapper(Parcel in) {
        readFromParcel(in);
    }

    /**
     * Set work source if any.
     */
    public void setWorkSource(WorkSource ws) {
        if (ws.getWorkChains() == null || ws.getWorkChains().size() == 0) {
            Slog.w(TAG, "Empty worksource!");
            return;
        }
        mWorkSource = ws;
    }

    /**
     * Write a int value.
     */
    public void writeInt(int val) {
        mTypes.add(EVENT_TYPE_INT);
        mValues.add(val);
    }

    /**
     * Write a long value.
     */
    public void writeLong(long val) {
        mTypes.add(EVENT_TYPE_LONG);
        mValues.add(val);
    }

    /**
     * Write a string value.
     */
    public void writeString(String val) {
        mTypes.add(EVENT_TYPE_STRING);
        // use empty string for null
        mValues.add(val == null ? "" : val);
    }

    /**
     * Write a float value.
     */
    public void writeFloat(float val) {
        mTypes.add(EVENT_TYPE_FLOAT);
        mValues.add(val);
    }

    /**
     * Write a storage value.
     */
    public void writeStorage(byte[] val) {
        mTypes.add(EVENT_TYPE_STORAGE);
        mValues.add(val);
    }

    /**
     * Write a boolean value.
     */
    public void writeBoolean(boolean val) {
        mTypes.add(EVENT_TYPE_INT);
        mValues.add(val ? 1 : 0);
    }

    public void writeToParcel(Parcel out, int flags) {
        if (DEBUG) {
            Slog.d(TAG,
                    "Writing " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs + " and "
                            + mTypes.size() + " elements.");
        }
        out.writeInt(mTag);
        out.writeLong(mElapsedTimeNs);
        out.writeLong(mWallClockTimeNs);
        if (mWorkSource != null) {
            List<WorkSource.WorkChain> workChains = mWorkSource.getWorkChains();
            // number of chains
            out.writeInt(workChains.size());
            for (int i = 0; i < workChains.size(); i++) {
                android.os.WorkSource.WorkChain wc = workChains.get(i);
                if (wc.getSize() == 0) {
                    Slog.w(TAG, "Empty work chain.");
                    out.writeInt(0);
                    continue;
                }
                if (wc.getUids().length != wc.getTags().length
                        || wc.getUids().length != wc.getSize()) {
                    Slog.w(TAG, "Malformated work chain.");
                    out.writeInt(0);
                    continue;
                }
                // number of nodes
                out.writeInt(wc.getSize());
                for (int j = 0; j < wc.getSize(); j++) {
                    out.writeInt(wc.getUids()[j]);
                    out.writeString(wc.getTags()[j] == null ? "" : wc.getTags()[j]);
                }
            }
        } else {
            // no chains
            out.writeInt(0);
        }
        out.writeInt(mTypes.size());
        for (int i = 0; i < mTypes.size(); i++) {
            out.writeInt(mTypes.get(i));
            switch (mTypes.get(i)) {
                case EVENT_TYPE_INT:
                    out.writeInt((int) mValues.get(i));
                    break;
                case EVENT_TYPE_LONG:
                    out.writeLong((long) mValues.get(i));
                    break;
                case EVENT_TYPE_FLOAT:
                    out.writeFloat((float) mValues.get(i));
                    break;
                case EVENT_TYPE_DOUBLE:
                    out.writeDouble((double) mValues.get(i));
                    break;
                case EVENT_TYPE_STRING:
                    out.writeString((String) mValues.get(i));
                    break;
                case EVENT_TYPE_STORAGE:
                    out.writeByteArray((byte[]) mValues.get(i));
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * Reads from parcel and appropriately fills member fields.
     */
    public void readFromParcel(Parcel in) {
        mTypes = new ArrayList<>();
        mValues = new ArrayList<>();
        mWorkSource = null;

        mTag = in.readInt();
        mElapsedTimeNs = in.readLong();
        mWallClockTimeNs = in.readLong();

        // Clear any data.
        if (DEBUG) {
            Slog.d(TAG, "Reading " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs);
        }
        // Set up worksource if present.
        int numWorkChains = in.readInt();
        if (numWorkChains > 0) {
            mWorkSource = new WorkSource();
            for (int i = 0; i < numWorkChains; i++) {
                android.os.WorkSource.WorkChain workChain = mWorkSource.createWorkChain();
                int workChainSize = in.readInt();
                for (int j = 0; j < workChainSize; j++) {
                    int uid = in.readInt();
                    String tag = in.readString();
                    workChain.addNode(uid, tag);
                }
            }
        }

        // Do the rest of the types.
        int numTypes = in.readInt();
        if (DEBUG) {
            Slog.d(TAG, "Reading " + numTypes + " elements");
        }
        for (int i = 0; i < numTypes; i++) {
            int type = in.readInt();
            mTypes.add(type);
            switch (type) {
                case EVENT_TYPE_INT:
                    mValues.add(in.readInt());
                    break;
                case EVENT_TYPE_LONG:
                    mValues.add(in.readLong());
                    break;
                case EVENT_TYPE_FLOAT:
                    mValues.add(in.readFloat());
                    break;
                case EVENT_TYPE_DOUBLE:
                    mValues.add(in.readDouble());
                    break;
                case EVENT_TYPE_STRING:
                    mValues.add(in.readString());
                    break;
                case EVENT_TYPE_STORAGE:
                    mValues.add(in.createByteArray());
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * Boilerplate for Parcel.
     */
    public int describeContents() {
        return 0;
    }
}
