/*
 * 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) {
            ArrayList<android.os.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;
    }
}
