/*
 * Copyright (C) 2018 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.carrierapi.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Parcel;
import android.telephony.AccessNetworkConstants;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.NetworkScan;
import android.telephony.NetworkScanRequest;
import android.telephony.RadioAccessSpecifier;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyScanManager;
import android.util.Log;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;

/**
 * Build, install and run the tests by running the commands below:
 *  make cts -j64
 *  cts-tradefed run cts -m CtsCarrierApiTestCases --test android.carrierapi.cts.NetworkScanApiTest
 */
@RunWith(AndroidJUnit4.class)
public class NetworkScanApiTest {
    private TelephonyManager mTelephonyManager;
    private PackageManager mPackageManager;
    private static final String TAG = "NetworkScanApiTest";
    private int mNetworkScanStatus;
    private static final int EVENT_NETWORK_SCAN_START = 100;
    private static final int EVENT_NETWORK_SCAN_RESULTS = 200;
    private static final int EVENT_NETWORK_SCAN_ERROR = 300;
    private static final int EVENT_NETWORK_SCAN_COMPLETED = 400;
    private List<CellInfo> mScanResults = null;
    private NetworkScanHandlerThread mTestHandlerThread;
    private Handler mHandler;
    private NetworkScan mNetworkScan;
    private NetworkScanRequest mNetworkScanRequest;
    private NetworkScanCallbackImpl mNetworkScanCallback;
    private static final int MAX_INIT_WAIT_MS = 60000; // 60 seconds
    private Object mLock = new Object();
    private boolean mReady;
    private int mErrorCode;
    /* All the following constants are used to construct NetworkScanRequest*/
    private static final int SCAN_TYPE = NetworkScanRequest.SCAN_TYPE_ONE_SHOT;
    private static final boolean INCREMENTAL_RESULTS = true;
    private static final int SEARCH_PERIODICITY_SEC = 5;
    private static final int MAX_SEARCH_TIME_SEC = 300;
    private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
    private static final ArrayList<String> MCC_MNC = new ArrayList<>();
    private static final RadioAccessSpecifier[] RADIO_ACCESS_SPECIFIERS = {
            new RadioAccessSpecifier(
                    AccessNetworkConstants.AccessNetworkType.GERAN,
                    null /* bands */,
                    null /* channels */),
            new RadioAccessSpecifier(
                    AccessNetworkConstants.AccessNetworkType.EUTRAN,
                    null /* bands */,
                    null /* channels */),
            new RadioAccessSpecifier(
                    AccessNetworkConstants.AccessNetworkType.UTRAN,
                    null /* bands */,
                    null /* channels */)
    };

    @Before
    public void setUp() throws Exception {
        mTelephonyManager = (TelephonyManager)
                InstrumentationRegistry.getContext().getSystemService(Context.TELEPHONY_SERVICE);
        mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
        mTestHandlerThread = new NetworkScanHandlerThread(TAG);
        mTestHandlerThread.start();
    }

    @After
    public void tearDown() throws Exception {
        mTestHandlerThread.quit();
    }

    private void waitUntilReady() {
        synchronized (mLock) {
            try {
                mLock.wait(MAX_INIT_WAIT_MS);
            } catch (InterruptedException ie) {
            }

            if (!mReady) {
                fail("NetworkScanApiTest failed to initialize");
            }
        }
    }

    private void setReady(boolean ready) {
        synchronized (mLock) {
            mReady = ready;
            mLock.notifyAll();
        }
    }

    private class NetworkScanHandlerThread extends HandlerThread {

        public NetworkScanHandlerThread(String name) {
            super(name);
        }

        @Override
        public void onLooperPrepared() {
            /* create a custom handler for the Handler Thread */
            mHandler = new Handler(mTestHandlerThread.getLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                        case EVENT_NETWORK_SCAN_START:
                            Log.d(TAG, "request network scan");
                            mNetworkScan = mTelephonyManager.requestNetworkScan(
                                    mNetworkScanRequest, mNetworkScanCallback);
                            break;
                        default:
                            Log.d(TAG, "Unknown Event " + msg.what);
                    }
                }
            };
        }
    }

    private class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
        @Override
        public void onResults(List<CellInfo> results) {
            Log.d(TAG, "onResults: " + results.toString());
            mNetworkScanStatus = EVENT_NETWORK_SCAN_RESULTS;
            mScanResults = results;
        }

        @Override
        public void onComplete() {
            Log.d(TAG, "onComplete");
            mNetworkScanStatus = EVENT_NETWORK_SCAN_COMPLETED;
            setReady(true);
        }

        @Override
        public void onError(int error) {
            Log.d(TAG, "onError: " + String.valueOf(error));
            mNetworkScanStatus = EVENT_NETWORK_SCAN_ERROR;
            mErrorCode = error;
            Log.d(TAG, "Stop the network scan");
            mNetworkScan.stopScan();
            setReady(true);
        }
    }

    private List<RadioAccessSpecifier> getRadioAccessSpecifier(List<CellInfo> allCellInfo) {
        List<RadioAccessSpecifier> radioAccessSpecifier = new ArrayList<>();
        List<Integer> lteChannels = new ArrayList<>();
        List<Integer> wcdmaChannels = new ArrayList<>();
        List<Integer> gsmChannels = new ArrayList<>();
        for (int i = 0; i < allCellInfo.size(); i++) {
            CellInfo cellInfo = allCellInfo.get(i);
            if (cellInfo instanceof CellInfoLte) {
                lteChannels.add(((CellInfoLte) cellInfo).getCellIdentity().getEarfcn());
            } else if (cellInfo instanceof CellInfoWcdma) {
                wcdmaChannels.add(((CellInfoWcdma) cellInfo).getCellIdentity().getUarfcn());
            } else if (cellInfo instanceof CellInfoGsm) {
                gsmChannels.add(((CellInfoGsm) cellInfo).getCellIdentity().getArfcn());
            }
        }
        if (!lteChannels.isEmpty()) {
            Log.d(TAG, "lte channels" + lteChannels.toString());
            int ranLte = AccessNetworkConstants.AccessNetworkType.EUTRAN;
            radioAccessSpecifier.add(
                    new RadioAccessSpecifier(ranLte, null /* bands */,
                            lteChannels.stream().mapToInt(i->i).toArray()));
        }
        if (!wcdmaChannels.isEmpty()) {
            Log.d(TAG, "wcdma channels" + wcdmaChannels.toString());
            int ranWcdma = AccessNetworkConstants.AccessNetworkType.UTRAN;
            radioAccessSpecifier.add(
                    new RadioAccessSpecifier(ranWcdma, null /* bands */,
                            wcdmaChannels.stream().mapToInt(i->i).toArray()));
        }
        if (!gsmChannels.isEmpty()) {
            Log.d(TAG, "gsm channels" + gsmChannels.toString());
            int ranGsm = AccessNetworkConstants.AccessNetworkType.GERAN;
            radioAccessSpecifier.add(
                    new RadioAccessSpecifier(ranGsm, null /* bands */,
                            gsmChannels.stream().mapToInt(i->i).toArray()));
        }
        return radioAccessSpecifier;
    }

    /**
     * Tests that the device properly requests a network scan.
     */
    @Test
    public void testRequestNetworkScan() throws InterruptedException {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            // Checks whether the cellular stack should be running on this device.
            Log.e(TAG, "No cellular support, the test will be skipped.");
            return;
        }
        if (!mTelephonyManager.hasCarrierPrivileges()) {
            fail("This test requires a SIM card with carrier privilege rule on it.");
        }

        // Make sure that there should be at least one entry.
        List<CellInfo> allCellInfo = mTelephonyManager.getAllCellInfo();
        if (allCellInfo == null) {
            fail("TelephonyManager.getAllCellInfo() returned NULL!");
        }
        if (allCellInfo.size() == 0) {
            fail("TelephonyManager.getAllCellInfo() returned zero-length list!");
        }

        // Construct a NetworkScanRequest
        List<RadioAccessSpecifier> radioAccessSpecifier = getRadioAccessSpecifier(allCellInfo);
        Log.d(TAG, "number of radioAccessSpecifier: " + radioAccessSpecifier.size());
        if (radioAccessSpecifier.isEmpty()) {
            RadioAccessSpecifier gsm = new RadioAccessSpecifier(
                    AccessNetworkConstants.AccessNetworkType.GERAN,
                    null /* bands */,
                    null /* channels */);
            RadioAccessSpecifier lte = new RadioAccessSpecifier(
                    AccessNetworkConstants.AccessNetworkType.EUTRAN,
                    null /* bands */,
                    null /* channels */);
            RadioAccessSpecifier wcdma = new RadioAccessSpecifier(
                    AccessNetworkConstants.AccessNetworkType.UTRAN,
                    null /* bands */,
                    null /* channels */);
            radioAccessSpecifier.add(gsm);
            radioAccessSpecifier.add(lte);
            radioAccessSpecifier.add(wcdma);
        }
        RadioAccessSpecifier[] radioAccessSpecifierArray =
                new RadioAccessSpecifier[radioAccessSpecifier.size()];
        mNetworkScanRequest = new NetworkScanRequest(
                NetworkScanRequest.SCAN_TYPE_ONE_SHOT /* scan type */,
                radioAccessSpecifier.toArray(radioAccessSpecifierArray),
                5 /* search periodicity */,
                60 /* max search time */,
                true /*enable incremental results*/,
                5 /* incremental results periodicity */,
                null /* List of PLMN ids (MCC-MNC) */);

        mNetworkScanCallback = new NetworkScanCallbackImpl();
        Message startNetworkScan = mHandler.obtainMessage(EVENT_NETWORK_SCAN_START);
        setReady(false);
        startNetworkScan.sendToTarget();
        waitUntilReady();

        Log.d(TAG, "mNetworkScanStatus: " + mNetworkScanStatus);
        assertTrue("The final scan status is not ScanCompleted or ScanError with an error "
                        + "code ERROR_MODEM_UNAVAILABLE or ERROR_UNSUPPORTED",
                isScanStatusValid());
    }

    private boolean isScanStatusValid() {
        // TODO(b/72162885): test the size of ScanResults is not zero after the blocking bug fixed.
        if ((mNetworkScanStatus == EVENT_NETWORK_SCAN_COMPLETED) && (mScanResults != null)) {
            // Scan complete.
            return true;
        }
        if ((mNetworkScanStatus == EVENT_NETWORK_SCAN_ERROR)
                && ((mErrorCode == NetworkScan.ERROR_MODEM_UNAVAILABLE)
                || (mErrorCode == NetworkScan.ERROR_UNSUPPORTED))) {
            // Scan error but the error type is allowed.
            return true;
        }
        return false;
    }

    private ArrayList<String> getPlmns() {
        ArrayList<String> mccMncs = new ArrayList<>();
        mccMncs.add("310260");
        mccMncs.add("310120");
        return mccMncs;
    }

    /**
     * To test its constructor and getters.
     */
    @Test
    public void testNetworkScanRequest_ConstructorAndGetters() {
        NetworkScanRequest networkScanRequest = new NetworkScanRequest(
                SCAN_TYPE,
                RADIO_ACCESS_SPECIFIERS,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                INCREMENTAL_RESULTS,
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                getPlmns());

        assertEquals("getScanType() returns wrong value",
                SCAN_TYPE, networkScanRequest.getScanType());
        assertEquals("getSpecifiers() returns wrong value",
                RADIO_ACCESS_SPECIFIERS, networkScanRequest.getSpecifiers());
        assertEquals("getSearchPeriodicity() returns wrong value",
                SEARCH_PERIODICITY_SEC, networkScanRequest.getSearchPeriodicity());
        assertEquals("getMaxSearchTime() returns wrong value",
                MAX_SEARCH_TIME_SEC, networkScanRequest.getMaxSearchTime());
        assertEquals("getIncrementalResults() returns wrong value",
                INCREMENTAL_RESULTS, networkScanRequest.getIncrementalResults());
        assertEquals("getIncrementalResultsPeriodicity() returns wrong value",
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                networkScanRequest.getIncrementalResultsPeriodicity());
        assertEquals("getPlmns() returns wrong value", getPlmns(), networkScanRequest.getPlmns());
        assertEquals("describeContents() returns wrong value",
                0, networkScanRequest.describeContents());
    }

    /**
     * To test its hashCode method.
     */
    @Test
    public void testNetworkScanRequestParcel_Hashcode() {
        NetworkScanRequest networkScanRequest1 = new NetworkScanRequest(
                SCAN_TYPE,
                RADIO_ACCESS_SPECIFIERS,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                INCREMENTAL_RESULTS,
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                getPlmns());

        NetworkScanRequest networkScanRequest2 = new NetworkScanRequest(
                SCAN_TYPE,
                RADIO_ACCESS_SPECIFIERS,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                INCREMENTAL_RESULTS,
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                getPlmns());

        NetworkScanRequest networkScanRequest3 = new NetworkScanRequest(
                SCAN_TYPE,
                null,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                false,
                0,
                getPlmns());

        assertEquals("hashCode() returns different hash code for same objects",
                networkScanRequest1.hashCode(), networkScanRequest2.hashCode());
        assertNotSame("hashCode() returns same hash code for different objects",
                networkScanRequest1.hashCode(), networkScanRequest3.hashCode());
    }

    /**
     * To test its comparision method.
     */
    @Test
    public void testNetworkScanRequestParcel_Equals() {
        NetworkScanRequest networkScanRequest1 = new NetworkScanRequest(
                SCAN_TYPE,
                RADIO_ACCESS_SPECIFIERS,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                INCREMENTAL_RESULTS,
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                getPlmns());

        NetworkScanRequest networkScanRequest2 = new NetworkScanRequest(
                SCAN_TYPE,
                RADIO_ACCESS_SPECIFIERS,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                INCREMENTAL_RESULTS,
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                getPlmns());

        assertTrue(networkScanRequest1.equals(networkScanRequest2));

        networkScanRequest2 = new NetworkScanRequest(
                SCAN_TYPE,
                RADIO_ACCESS_SPECIFIERS,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                INCREMENTAL_RESULTS,
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                null /* List of PLMN ids (MCC-MNC) */);
        assertFalse(networkScanRequest1.equals(networkScanRequest2));
    }

    /**
     * To test its writeToParcel and createFromParcel methods.
     */
    @Test
    public void testNetworkScanRequestParcel_Parcel() {
        NetworkScanRequest networkScanRequest = new NetworkScanRequest(
                SCAN_TYPE,
                null /* Radio Access Specifier */,
                SEARCH_PERIODICITY_SEC,
                MAX_SEARCH_TIME_SEC,
                INCREMENTAL_RESULTS,
                INCREMENTAL_RESULTS_PERIODICITY_SEC,
                getPlmns());

        Parcel p = Parcel.obtain();
        networkScanRequest.writeToParcel(p, 0);
        p.setDataPosition(0);
        NetworkScanRequest newnsr = NetworkScanRequest.CREATOR.createFromParcel(p);
        assertTrue(networkScanRequest.equals(newnsr));

    }
}
