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

/** @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;

    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]));
    }
}
