/*
 * Copyright (C) 2016 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.net.metrics;

import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;

import com.android.internal.util.MessageUtils;

/**
 * Event class used to record error events when parsing DHCP response packets.
 * {@hide}
 */
@SystemApi
@TestApi
public final class DhcpErrorEvent implements IpConnectivityLog.Event {
    public static final int L2_ERROR   = 1;
    public static final int L3_ERROR   = 2;
    public static final int L4_ERROR   = 3;
    public static final int DHCP_ERROR = 4;
    public static final int MISC_ERROR = 5;

    // error code byte format (MSB to LSB):
    // byte 0: error type
    // byte 1: error subtype
    // byte 2: unused
    // byte 3: optional code
    /** @hide */
    public final int errorCode;

    private static final int L2_ERROR_TYPE = L2_ERROR << 8;
    private static final int L3_ERROR_TYPE = L3_ERROR << 8;
    private static final int L4_ERROR_TYPE = L4_ERROR << 8;
    private static final int DHCP_ERROR_TYPE = DHCP_ERROR << 8;
    private static final int MISC_ERROR_TYPE = MISC_ERROR << 8;

    public static final int L2_TOO_SHORT               = (L2_ERROR_TYPE | 0x1) << 16;
    public static final int L2_WRONG_ETH_TYPE          = (L2_ERROR_TYPE | 0x2) << 16;

    public static final int L3_TOO_SHORT               = (L3_ERROR_TYPE | 0x1) << 16;
    public static final int L3_NOT_IPV4                = (L3_ERROR_TYPE | 0x2) << 16;
    public static final int L3_INVALID_IP              = (L3_ERROR_TYPE | 0x3) << 16;

    public static final int L4_NOT_UDP                 = (L4_ERROR_TYPE | 0x1) << 16;
    public static final int L4_WRONG_PORT              = (L4_ERROR_TYPE | 0x2) << 16;

    public static final int BOOTP_TOO_SHORT            = (DHCP_ERROR_TYPE | 0x1) << 16;
    public static final int DHCP_BAD_MAGIC_COOKIE      = (DHCP_ERROR_TYPE | 0x2) << 16;
    public static final int DHCP_INVALID_OPTION_LENGTH = (DHCP_ERROR_TYPE | 0x3) << 16;
    public static final int DHCP_NO_MSG_TYPE           = (DHCP_ERROR_TYPE | 0x4) << 16;
    public static final int DHCP_UNKNOWN_MSG_TYPE      = (DHCP_ERROR_TYPE | 0x5) << 16;
    public static final int DHCP_NO_COOKIE             = (DHCP_ERROR_TYPE | 0x6) << 16;

    public static final int BUFFER_UNDERFLOW           = (MISC_ERROR_TYPE | 0x1) << 16;
    public static final int RECEIVE_ERROR              = (MISC_ERROR_TYPE | 0x2) << 16;
    public static final int PARSING_ERROR              = (MISC_ERROR_TYPE | 0x3) << 16;

    public DhcpErrorEvent(int errorCode) {
        this.errorCode = errorCode;
    }

    private DhcpErrorEvent(Parcel in) {
        this.errorCode = in.readInt();
    }

    /** @hide */
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(errorCode);
    }

    /** @hide */
    @Override
    public int describeContents() {
        return 0;
    }

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

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

    public static int errorCodeWithOption(int errorCode, int option) {
        return (0xFFFF0000 & errorCode) | (0xFF & option);
    }

    @Override
    public String toString() {
        return String.format("DhcpErrorEvent(%s)", Decoder.constants.get(errorCode));
    }

    final static class Decoder {
        static final SparseArray<String> constants = MessageUtils.findMessageNames(
                new Class[]{DhcpErrorEvent.class},
                new String[]{"L2_", "L3_", "L4_", "BOOTP_", "DHCP_", "BUFFER_", "RECEIVE_",
                "PARSING_"});
    }
}
