/*
 * 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.ext.services.watchdog;

import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;

import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.RemoteCallback;
import android.provider.DeviceConfig;
import android.service.watchdog.ExplicitHealthCheckService;
import android.service.watchdog.IExplicitHealthCheckService;

import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ServiceTestRule;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * Contains the base tests that does not rely on the specific algorithm implementation.
 */
public class ExplicitHealthCheckServiceImplTest {
    private static final String NETWORK_STACK_CONNECTOR_CLASS =
            "android.net.INetworkStackConnector";

    private final Context mContext = InstrumentationRegistry.getContext();
    private IExplicitHealthCheckService mService;
    private String mNetworkStackPackageName;

    @Rule
    public ServiceTestRule mServiceTestRule;

    @Before
    public void setUp() throws Exception {
        InstrumentationRegistry
                .getInstrumentation()
                .getUiAutomation()
                .adoptShellPermissionIdentity(
                        Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE,
                        Manifest.permission.WRITE_DEVICE_CONFIG);

        mServiceTestRule = new ServiceTestRule();
        mService = IExplicitHealthCheckService.Stub.asInterface(
                mServiceTestRule.bindService(getExtServiceIntent()));
        mNetworkStackPackageName = getNetworkStackPackage();
        assumeFalse(mNetworkStackPackageName == null);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
                ExplicitHealthCheckServiceImpl.PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS,
                Long.toString(ExplicitHealthCheckServiceImpl.DEFAULT_REQUEST_TIMEOUT_MILLIS),
                false);
    }

    @After
    public void tearDown() {
        InstrumentationRegistry
                .getInstrumentation()
                .getUiAutomation()
                .dropShellPermissionIdentity();
    }

    @Test
    public void testHealthCheckSupportedPackage() throws Exception {
        List<PackageConfig> supportedPackages = new ArrayList<>();
        CountDownLatch latch = new CountDownLatch(1);

        mService.getSupportedPackages(new RemoteCallback(result -> {
            supportedPackages.addAll(result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES));
            latch.countDown();
        }));
        latch.await();

        // TODO: Support DeviceConfig changes for the health check timeout
        assertThat(supportedPackages).hasSize(1);
        assertThat(supportedPackages.get(0).getPackageName())
                .isEqualTo(mNetworkStackPackageName);
        assertThat(supportedPackages.get(0).getHealthCheckTimeoutMillis())
                .isEqualTo(ExplicitHealthCheckServiceImpl.DEFAULT_REQUEST_TIMEOUT_MILLIS);
    }

    @Test
    public void testHealthCheckRequests() throws Exception {
        List<String> requestedPackages = new ArrayList<>();
        CountDownLatch latch1 = new CountDownLatch(1);
        CountDownLatch latch2 = new CountDownLatch(1);
        CountDownLatch latch3 = new CountDownLatch(1);

        // Initially, no health checks requested
        mService.getRequestedPackages(new RemoteCallback(result -> {
            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
            latch1.countDown();
        }));

        // Verify that no health checks requested
        latch1.await();
        assertThat(requestedPackages).isEmpty();

        // Then request health check
        mService.request(mNetworkStackPackageName);

        // TODO(gavincorkery): Eliminate the need for this sleep
        Thread.sleep(1000);
        // Verify that health check is requested for network stack
        mService.getRequestedPackages(new RemoteCallback(result -> {
            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
            latch2.countDown();
        }));
        latch2.await();
        assertThat(requestedPackages).hasSize(1);
        assertThat(requestedPackages.get(0)).isEqualTo(mNetworkStackPackageName);

        // Then cancel health check
        requestedPackages.clear();
        mService.cancel(mNetworkStackPackageName);

        // Verify that health check is cancelled for network stack
        mService.getRequestedPackages(new RemoteCallback(result -> {
            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
            latch3.countDown();
        }));
        latch3.await();
        assertThat(requestedPackages).isEmpty();
    }

    private String getNetworkStackPackage() {
        Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
        if (comp != null) {
            return comp.getPackageName();
        } else {
            // On Go devices, or any device that does not ship the network stack module.
            // The network stack will live in system_server process, so no need to monitor.
            return null;
        }
    }

    private Intent getExtServiceIntent() {
        ComponentName component = getExtServiceComponentNameLocked();
        if (component == null) {
            fail("Health check service not found");
        }
        Intent intent = new Intent();
        intent.setComponent(component);
        return intent;
    }

    private ComponentName getExtServiceComponentNameLocked() {
        ServiceInfo serviceInfo = getExtServiceInfoLocked();
        if (serviceInfo == null) {
            return null;
        }

        final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
        if (!Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE
                .equals(serviceInfo.permission)) {
            return null;
        }
        return name;
    }

    private ServiceInfo getExtServiceInfoLocked() {
        final String packageName =
                mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
        if (packageName == null) {
            return null;
        }

        final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
        intent.setPackage(packageName);
        final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
            return null;
        }
        return resolveInfo.serviceInfo;
    }
}
