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

import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable;

import android.content.Context;
import android.net.DhcpResultsParcelable;
import android.net.Layer2PacketParcelable;
import android.net.LinkProperties;
import android.net.networkstack.ModuleNetworkStackClient;
import android.os.ConditionVariable;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;


/**
 * Utilities and wrappers to simplify communication with IpClient, which lives in the NetworkStack
 * process.
 *
 * @hide
 */
public class IpClientUtil {
    // TODO: remove with its callers
    public static final String DUMP_ARG = "ipclient";

    /**
     * Subclass of {@link IpClientCallbacks} allowing clients to block until provisioning is
     * complete with {@link WaitForProvisioningCallbacks#waitForProvisioning()}.
     */
    public static class WaitForProvisioningCallbacks extends IpClientCallbacks {
        private final ConditionVariable mCV = new ConditionVariable();
        private LinkProperties mCallbackLinkProperties;

        /**
         * Block until either {@link #onProvisioningSuccess(LinkProperties)} or
         * {@link #onProvisioningFailure(LinkProperties)} is called.
         */
        public LinkProperties waitForProvisioning() {
            mCV.block();
            return mCallbackLinkProperties;
        }

        @Override
        public void onProvisioningSuccess(LinkProperties newLp) {
            mCallbackLinkProperties = newLp;
            mCV.open();
        }

        @Override
        public void onProvisioningFailure(LinkProperties newLp) {
            mCallbackLinkProperties = null;
            mCV.open();
        }
    }

    /**
     * Create a new IpClient.
     *
     * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of
     * {@link IIpClientCallbacks}.
     * @see {@link ModuleNetworkStackClient#makeIpClient(String, IIpClientCallbacks)}
     */
    public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) {
        ModuleNetworkStackClient.getInstance(context)
                .makeIpClient(ifName, new IpClientCallbacksProxy(callback));
    }

    /**
     * Wrapper to relay calls from {@link IIpClientCallbacks} to {@link IpClientCallbacks}.
     */
    private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub {
        protected final IpClientCallbacks mCb;

        /**
         * Create a new IpClientCallbacksProxy.
         */
        public IpClientCallbacksProxy(IpClientCallbacks cb) {
            mCb = cb;
        }

        @Override
        public void onIpClientCreated(IIpClient ipClient) {
            mCb.onIpClientCreated(ipClient);
        }

        @Override
        public void onPreDhcpAction() {
            mCb.onPreDhcpAction();
        }

        @Override
        public void onPostDhcpAction() {
            mCb.onPostDhcpAction();
        }

        // This is purely advisory and not an indication of provisioning
        // success or failure.  This is only here for callers that want to
        // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
        // DHCPv4 or static IPv4 configuration failure or success can be
        // determined by whether or not the passed-in DhcpResults object is
        // null or not.
        @Override
        public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {
            mCb.onNewDhcpResults(fromStableParcelable(dhcpResults));
            mCb.onNewDhcpResults(dhcpResults);
        }

        @Override
        public void onProvisioningSuccess(LinkProperties newLp) {
            mCb.onProvisioningSuccess(newLp);
        }
        @Override
        public void onProvisioningFailure(LinkProperties newLp) {
            mCb.onProvisioningFailure(newLp);
        }

        // Invoked on LinkProperties changes.
        @Override
        public void onLinkPropertiesChange(LinkProperties newLp) {
            mCb.onLinkPropertiesChange(newLp);
        }

        // Called when the internal IpReachabilityMonitor (if enabled) has
        // detected the loss of a critical number of required neighbors.
        @Override
        public void onReachabilityLost(String logMsg) {
            mCb.onReachabilityLost(logMsg);
        }

        // Called when the IpClient state machine terminates.
        @Override
        public void onQuit() {
            mCb.onQuit();
        }

        // Install an APF program to filter incoming packets.
        @Override
        public void installPacketFilter(byte[] filter) {
            mCb.installPacketFilter(filter);
        }

        // Asynchronously read back the APF program & data buffer from the wifi driver.
        // Due to Wifi HAL limitations, the current implementation only supports dumping the entire
        // buffer. In response to this request, the driver returns the data buffer asynchronously
        // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
        @Override
        public void startReadPacketFilter() {
            mCb.startReadPacketFilter();
        }

        // If multicast filtering cannot be accomplished with APF, this function will be called to
        // actuate multicast filtering using another means.
        @Override
        public void setFallbackMulticastFilter(boolean enabled) {
            mCb.setFallbackMulticastFilter(enabled);
        }

        // Enabled/disable Neighbor Discover offload functionality. This is
        // called, for example, whenever 464xlat is being started or stopped.
        @Override
        public void setNeighborDiscoveryOffload(boolean enable) {
            mCb.setNeighborDiscoveryOffload(enable);
        }

        // Invoked on starting preconnection process.
        @Override
        public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {
            mCb.onPreconnectionStart(packets);
        }

        @Override
        public int getInterfaceVersion() {
            return this.VERSION;
        }

        @Override
        public String getInterfaceHash() {
            return this.HASH;
        }
    }

    /**
     * Dump logs for the specified IpClient.
     * TODO: remove callers and delete
     */
    public static void dumpIpClient(
            IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("IpClient logs have moved to dumpsys network_stack");
    }
}
