/*
 * 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.net;

import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.annotations.VisibleForTesting;

/**
 * This class encapsulates all the configuration parameters needed to create IPsec transforms and
 * policies.
 *
 * @hide
 */
public final class IpSecConfig implements Parcelable {
    private static final String TAG = "IpSecConfig";

    // MODE_TRANSPORT or MODE_TUNNEL
    private int mMode = IpSecTransform.MODE_TRANSPORT;

    // Needs to be valid only for tunnel mode
    // Preventing this from being null simplifies Java->Native binder
    private String mLocalAddress = "";

    // Preventing this from being null simplifies Java->Native binder
    private String mRemoteAddress = "";

    // The underlying Network that represents the "gateway" Network
    // for outbound packets. It may also be used to select packets.
    private Network mNetwork;

    /**
     * This class captures the parameters that specifically apply to inbound or outbound traffic.
     */
    public static class Flow {
        // Minimum requirements for identifying a transform
        // SPI identifying the IPsec flow in packet processing
        // and a remote IP address
        private int mSpiResourceId = IpSecManager.INVALID_RESOURCE_ID;

        // Encryption Algorithm
        private IpSecAlgorithm mEncryption;

        // Authentication Algorithm
        private IpSecAlgorithm mAuthentication;

        // Authenticated Encryption Algorithm
        private IpSecAlgorithm mAuthenticatedEncryption;

        @Override
        public String toString() {
            return new StringBuilder()
                    .append("{mSpiResourceId=")
                    .append(mSpiResourceId)
                    .append(", mEncryption=")
                    .append(mEncryption)
                    .append(", mAuthentication=")
                    .append(mAuthentication)
                    .append(", mAuthenticatedEncryption=")
                    .append(mAuthenticatedEncryption)
                    .append("}")
                    .toString();
        }

        static boolean equals(IpSecConfig.Flow lhs, IpSecConfig.Flow rhs) {
            if (lhs == null || rhs == null) return (lhs == rhs);
            return (lhs.mSpiResourceId == rhs.mSpiResourceId
                    && IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
                    && IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication));
        }
    }

    private final Flow[] mFlow = new Flow[] {new Flow(), new Flow()};

    // For tunnel mode IPv4 UDP Encapsulation
    // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
    private int mEncapType = IpSecTransform.ENCAP_NONE;
    private int mEncapSocketResourceId = IpSecManager.INVALID_RESOURCE_ID;
    private int mEncapRemotePort;

    // An interval, in seconds between the NattKeepalive packets
    private int mNattKeepaliveInterval;

    /** Set the mode for this IPsec transform */
    public void setMode(int mode) {
        mMode = mode;
    }

    /** Set the local IP address for Tunnel mode */
    public void setLocalAddress(String localAddress) {
        if (localAddress == null) {
            throw new IllegalArgumentException("localAddress may not be null!");
        }
        mLocalAddress = localAddress;
    }

    /** Set the remote IP address for this IPsec transform */
    public void setRemoteAddress(String remoteAddress) {
        if (remoteAddress == null) {
            throw new IllegalArgumentException("remoteAddress may not be null!");
        }
        mRemoteAddress = remoteAddress;
    }

    /** Set the SPI for a given direction by resource ID */
    public void setSpiResourceId(int direction, int resourceId) {
        mFlow[direction].mSpiResourceId = resourceId;
    }

    /** Set the encryption algorithm for a given direction */
    public void setEncryption(int direction, IpSecAlgorithm encryption) {
        mFlow[direction].mEncryption = encryption;
    }

    /** Set the authentication algorithm for a given direction */
    public void setAuthentication(int direction, IpSecAlgorithm authentication) {
        mFlow[direction].mAuthentication = authentication;
    }

    /** Set the authenticated encryption algorithm for a given direction */
    public void setAuthenticatedEncryption(int direction, IpSecAlgorithm authenticatedEncryption) {
        mFlow[direction].mAuthenticatedEncryption = authenticatedEncryption;
    }

    public void setNetwork(Network network) {
        mNetwork = network;
    }

    public void setEncapType(int encapType) {
        mEncapType = encapType;
    }

    public void setEncapSocketResourceId(int resourceId) {
        mEncapSocketResourceId = resourceId;
    }

    public void setEncapRemotePort(int port) {
        mEncapRemotePort = port;
    }

    public void setNattKeepaliveInterval(int interval) {
        mNattKeepaliveInterval = interval;
    }

    // Transport or Tunnel
    public int getMode() {
        return mMode;
    }

    public String getLocalAddress() {
        return mLocalAddress;
    }

    public int getSpiResourceId(int direction) {
        return mFlow[direction].mSpiResourceId;
    }

    public String getRemoteAddress() {
        return mRemoteAddress;
    }

    public IpSecAlgorithm getEncryption(int direction) {
        return mFlow[direction].mEncryption;
    }

    public IpSecAlgorithm getAuthentication(int direction) {
        return mFlow[direction].mAuthentication;
    }

    public IpSecAlgorithm getAuthenticatedEncryption(int direction) {
        return mFlow[direction].mAuthenticatedEncryption;
    }

    public Network getNetwork() {
        return mNetwork;
    }

    public int getEncapType() {
        return mEncapType;
    }

    public int getEncapSocketResourceId() {
        return mEncapSocketResourceId;
    }

    public int getEncapRemotePort() {
        return mEncapRemotePort;
    }

    public int getNattKeepaliveInterval() {
        return mNattKeepaliveInterval;
    }

    // Parcelable Methods

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

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mMode);
        out.writeString(mLocalAddress);
        out.writeString(mRemoteAddress);
        out.writeParcelable(mNetwork, flags);
        out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthentication, flags);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption, flags);
        out.writeInt(mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption, flags);
        out.writeInt(mEncapType);
        out.writeInt(mEncapSocketResourceId);
        out.writeInt(mEncapRemotePort);
        out.writeInt(mNattKeepaliveInterval);
    }

    @VisibleForTesting
    public IpSecConfig() {}

    private IpSecConfig(Parcel in) {
        mMode = in.readInt();
        mLocalAddress = in.readString();
        mRemoteAddress = in.readString();
        mNetwork = (Network) in.readParcelable(Network.class.getClassLoader());
        mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId = in.readInt();
        mFlow[IpSecTransform.DIRECTION_IN].mEncryption =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        mFlow[IpSecTransform.DIRECTION_IN].mAuthentication =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId = in.readInt();
        mFlow[IpSecTransform.DIRECTION_OUT].mEncryption =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        mEncapType = in.readInt();
        mEncapSocketResourceId = in.readInt();
        mEncapRemotePort = in.readInt();
        mNattKeepaliveInterval = in.readInt();
    }

    @Override
    public String toString() {
        StringBuilder strBuilder = new StringBuilder();
        strBuilder
                .append("{mMode=")
                .append(mMode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT")
                .append(", mLocalAddress=")
                .append(mLocalAddress)
                .append(", mRemoteAddress=")
                .append(mRemoteAddress)
                .append(", mNetwork=")
                .append(mNetwork)
                .append(", mEncapType=")
                .append(mEncapType)
                .append(", mEncapSocketResourceId=")
                .append(mEncapSocketResourceId)
                .append(", mEncapRemotePort=")
                .append(mEncapRemotePort)
                .append(", mNattKeepaliveInterval=")
                .append(mNattKeepaliveInterval)
                .append(", mFlow[OUT]=")
                .append(mFlow[IpSecTransform.DIRECTION_OUT])
                .append(", mFlow[IN]=")
                .append(mFlow[IpSecTransform.DIRECTION_IN])
                .append("}");

        return strBuilder.toString();
    }

    public static final Parcelable.Creator<IpSecConfig> CREATOR =
            new Parcelable.Creator<IpSecConfig>() {
                public IpSecConfig createFromParcel(Parcel in) {
                    return new IpSecConfig(in);
                }

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

    @VisibleForTesting
    /** Equals method used for testing */
    public static boolean equals(IpSecConfig lhs, IpSecConfig rhs) {
        if (lhs == null || rhs == null) return (lhs == rhs);
        return (lhs.mMode == rhs.mMode
                && lhs.mLocalAddress.equals(rhs.mLocalAddress)
                && lhs.mRemoteAddress.equals(rhs.mRemoteAddress)
                && ((lhs.mNetwork != null && lhs.mNetwork.equals(rhs.mNetwork))
                        || (lhs.mNetwork == rhs.mNetwork))
                && lhs.mEncapType == rhs.mEncapType
                && lhs.mEncapSocketResourceId == rhs.mEncapSocketResourceId
                && lhs.mEncapRemotePort == rhs.mEncapRemotePort
                && lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
                && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_OUT],
                        rhs.mFlow[IpSecTransform.DIRECTION_OUT])
                && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_IN],
                        rhs.mFlow[IpSecTransform.DIRECTION_IN]));
    }
}
