/*
 * Copyright (C) 2020 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.internal.net.ipsec.ike.keepalive;

import static android.net.SocketKeepalive.ERROR_HARDWARE_ERROR;
import static android.net.SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES;
import static android.net.SocketKeepalive.ERROR_INVALID_INTERVAL;
import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
import static android.net.SocketKeepalive.ERROR_INVALID_LENGTH;
import static android.net.SocketKeepalive.ERROR_INVALID_NETWORK;
import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
import static android.net.SocketKeepalive.ERROR_SOCKET_NOT_IDLE;
import static android.net.SocketKeepalive.ERROR_UNSUPPORTED;
import static android.net.ipsec.ike.IkeManager.getIkeLog;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.IpSecManager.UdpEncapsulationSocket;
import android.net.Network;
import android.net.SocketKeepalive;

import java.io.IOException;
import java.net.Inet4Address;
import java.util.concurrent.Executors;

/** This class provides methods to manage hardware offload NAT-T keepalive. */
public class HardwareKeepaliveImpl implements IkeNattKeepalive.NattKeepalive {
    private static final String TAG = "HardwareKeepaliveImpl";

    private final int mKeepaliveDelaySeconds;
    private final SocketKeepalive mSocketKeepalive;
    private final HardwareKeepaliveCallback mHardwareKeepaliveCb;

    /** Construct an instance of HardwareKeepaliveImpl */
    public HardwareKeepaliveImpl(
            Context context,
            int keepaliveDelaySeconds,
            Inet4Address src,
            Inet4Address dest,
            UdpEncapsulationSocket socket,
            Network network,
            HardwareKeepaliveCallback hardwareKeepaliveCb)
            throws IOException {
        // Setup for hardware offload keepalive. Fail to create mSocketKeepalive will cause
        // MySocketKeepaliveCb#onError to be fired
        mKeepaliveDelaySeconds = keepaliveDelaySeconds;
        mHardwareKeepaliveCb = hardwareKeepaliveCb;

        ConnectivityManager connMgr =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        mSocketKeepalive =
                connMgr.createSocketKeepalive(
                        network,
                        socket,
                        src,
                        dest,
                        Executors.newSingleThreadExecutor(),
                        new MySocketKeepaliveCb());
    }

    @Override
    public void start() {
        mSocketKeepalive.start(mKeepaliveDelaySeconds);
    }

    @Override
    public void stop() {
        mSocketKeepalive.stop();
    }

    @Override
    public void onAlarmFired() {
        // Do thing. Should never be called
    }

    /** Callback interface to receive states change of hardware keepalive */
    public interface HardwareKeepaliveCallback {
        /** Called when there is a hardware error for keepalive. */
        void onHardwareOffloadError();

        /**
         * Called when there is a network or configuration error which cause sending keepalive
         * packet to fail
         */
        void onNetworkError();
    }

    private class MySocketKeepaliveCb extends SocketKeepalive.Callback {
        @Override
        public void onError(int error) {
            getIkeLog().d(TAG, "Hardware offload failed on error: " + error);
            switch (error) {
                case ERROR_INVALID_NETWORK: // fallthrough
                case ERROR_INVALID_IP_ADDRESS: // fallthrough
                case ERROR_INVALID_PORT: // fallthrough
                case ERROR_INVALID_LENGTH: // fallthrough
                case ERROR_INVALID_INTERVAL: // fallthrough
                case ERROR_INVALID_SOCKET: // fallthrough
                case ERROR_SOCKET_NOT_IDLE: // fallthrough
                    mHardwareKeepaliveCb.onNetworkError();
                    return;
                case ERROR_UNSUPPORTED: // fallthrough
                case ERROR_HARDWARE_ERROR: // fallthrough
                case ERROR_INSUFFICIENT_RESOURCES:
                    mHardwareKeepaliveCb.onHardwareOffloadError();
                    return;
                default:
                    mHardwareKeepaliveCb.onNetworkError();
            }
        }
    }
}
