/*
 * Copyright (C) 2019 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 com.android.tradefed.cluster;

import com.android.tradefed.log.LogUtil.CLog;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/** A class to encapsulate cluster command events to be uploaded. */
public class ClusterCommandEvent implements IClusterEvent {

    public static final String DATA_KEY_ERROR = "error";
    public static final String DATA_KEY_SUMMARY = "summary";
    public static final String DATA_KEY_SETUP_TIME_MILLIS = "setup_time_millis";
    public static final String DATA_KEY_FETCH_BUILD_TIME_MILLIS = "fetch_build_time_millis";
    public static final String DATA_KEY_TOTAL_TEST_COUNT = "total_test_count";
    public static final String DATA_KEY_FAILED_TEST_COUNT = "failed_test_count";
    public static final String DATA_KEY_PASSED_TEST_COUNT = "passed_test_count";
    public static final String DATA_KEY_FAILED_TEST_RUN_COUNT = "failed_test_run_count";

    // Maximum size of an individual data string value.
    public static final int MAX_DATA_STRING_SIZE = 4095;

    public enum Type {
        AllocationFailed,
        ConfigurationError,
        FetchFailed,
        ExecuteFailed,
        InvocationInitiated,
        InvocationStarted,
        InvocationFailed,
        InvocationEnded,
        InvocationCompleted,
        TestRunInProgress,
        TestEnded
    }

    private long mTimestamp;
    private Type mType;
    private String mCommandTaskId;
    private String mAttemptId;
    private String mHostName;
    private InvocationStatus mInvocationStatus;
    private Map<String, Object> mData = new HashMap<>();
    private Set<String> mDeviceSerials;

    private ClusterCommandEvent() {}

    public String getHostName() {
        return mHostName;
    }

    public long getTimestamp() {
        return mTimestamp;
    }

    public Type getType() {
        return mType;
    }

    public String getCommandTaskId() {
        return mCommandTaskId;
    }

    public String getAttemptId() {
        return mAttemptId;
    }

    public InvocationStatus getInvocationStatus() {
        return mInvocationStatus;
    }

    public Map<String, Object> getData() {
        return mData;
    }

    public Set<String> getDeviceSerials() {
        return mDeviceSerials;
    }

    public static class Builder {

        private long mTimestamp = System.currentTimeMillis();
        private Type mType;
        private String mCommandTaskId;
        private String mAttemptId;
        private String mHostName;
        private InvocationStatus mInvocationStatus;
        private Map<String, Object> mData = new HashMap<>();
        private Set<String> mDeviceSerials = new HashSet<>();

        public Builder() {}

        public Builder setTimestamp(final long timestamp) {
            mTimestamp = timestamp;
            return this;
        }

        public Builder setType(final Type type) {
            mType = type;
            return this;
        }

        public Builder setCommandTaskId(final String commandTaskId) {
            mCommandTaskId = commandTaskId;
            return this;
        }

        public Builder setAttemptId(final String attemptId) {
            mAttemptId = attemptId;
            return this;
        }

        public Builder setHostName(final String hostName) {
            mHostName = hostName;
            return this;
        }

        public Builder setInvocationStatus(final InvocationStatus invocationStatus) {
            mInvocationStatus = invocationStatus;
            return this;
        }

        public Builder setData(final String name, final Object value) {
            if (value instanceof String && ((String) value).length() > MAX_DATA_STRING_SIZE) {
                CLog.w(
                        String.format(
                                "Data for '%s' exceeds %d characters, and has been truncated.",
                                name, MAX_DATA_STRING_SIZE));
                mData.put(name, ((String) value).substring(0, MAX_DATA_STRING_SIZE));
            } else {
                mData.put(name, value);
            }
            return this;
        }

        public Builder setDeviceSerials(final Set<String> deviceSerials) {
            mDeviceSerials = deviceSerials;
            return this;
        }

        public Builder addDeviceSerial(final String deviceSerial) {
            mDeviceSerials.add(deviceSerial);
            return this;
        }

        public ClusterCommandEvent build() {
            final ClusterCommandEvent obj = new ClusterCommandEvent();
            obj.mTimestamp = mTimestamp;
            obj.mType = mType;
            obj.mCommandTaskId = mCommandTaskId;
            obj.mAttemptId = mAttemptId;
            obj.mHostName = mHostName;
            obj.mInvocationStatus = mInvocationStatus;
            obj.mData = new HashMap<>(mData);
            obj.mDeviceSerials = mDeviceSerials;
            return obj;
        }
    }

    /**
     * Creates a base {@link Builder}.
     *
     * @return a {@link Builder}.
     */
    public static Builder createEventBuilder() {
        return createEventBuilder(null);
    }

    /**
     * Creates a base {@link Builder} for the given {@link ClusterCommand}.
     *
     * @return a {@link Builder}.
     */
    public static Builder createEventBuilder(final ClusterCommand command) {
        final ClusterCommandEvent.Builder builder = new ClusterCommandEvent.Builder();
        if (command != null) {
            builder.setCommandTaskId(command.getTaskId());
            builder.setAttemptId(command.getAttemptId());
        }
        return builder;
    }

    /** {@inheritDoc} */
    @Override
    public JSONObject toJSON() throws JSONException {
        final JSONObject json = new JSONObject();
        json.put("type", this.getType().toString());
        // event time should be in POSIX timestamp.
        json.put("time", this.getTimestamp() / 1000);
        json.put("task_id", this.getCommandTaskId());
        json.put("attempt_id", this.getAttemptId());
        json.put("hostname", this.getHostName());
        // TODO(b/79583735): deprecated.
        if (!this.getDeviceSerials().isEmpty()) {
            json.put("device_serial", this.getDeviceSerials().iterator().next());
        }
        json.put("device_serials", new JSONArray(this.getDeviceSerials()));
        if (mInvocationStatus != null) {
            json.put("invocation_status", mInvocationStatus.toJSON());
        }
        json.put("data", new JSONObject(this.getData()));
        return json;
    }

    @Override
    public String toString() {
        String str = null;
        try {
            str = toJSON().toString();
        } catch (final JSONException e) {
            // ignore
        }
        return str;
    }
}
