/*
 * Copyright (C) 2015 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.car.apitest;

import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
import static com.android.compatibility.common.util.TestUtils.BooleanSupplierWithThrow;

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

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

import android.annotation.NonNull;
import android.app.UiAutomation;
import android.car.Car;
import android.content.ComponentName;
import android.content.Context;
import android.content.ServiceConnection;
import android.hardware.automotive.vehicle.V2_0.InitialUserInfoRequestType;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestName;

import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

abstract class CarApiTestBase {

    private static final String TAG = CarApiTestBase.class.getSimpleName();

    protected static final long DEFAULT_WAIT_TIMEOUT_MS = 60_000;

    /**
     * Constant used to wait blindly, when there is no condition that can be checked.
     */
    private static final int SUSPEND_TIMEOUT_MS = 5_000;

    /**
     * How long to sleep (multiple times) while waiting for a condition.
     */
    private static final int SMALL_NAP_MS = 100;

    protected static final Context sContext = InstrumentationRegistry.getInstrumentation()
            .getTargetContext();

    private Car mCar;

    protected final DefaultServiceConnectionListener mConnectionListener =
            new DefaultServiceConnectionListener();

    // NOTE: public as required by JUnit; tests should call getTestName() instead
    @Rule
    public final TestName mTestName = new TestName();

    @Before
    public final void setFixturesAndConnectToCar() throws Exception {
        Log.d(TAG, "setFixturesAndConnectToCar() for " + mTestName.getMethodName());

        mCar = Car.createCar(getContext(), mConnectionListener);
        mCar.connect();
        mConnectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
    }

    @After
    public final void disconnectCar() throws Exception {
        if (mCar == null) {
            Log.wtf(TAG, "no mCar on " + getTestName() + ".tearDown()");
            return;
        }
        mCar.disconnect();
    }

    protected Car getCar() {
        return mCar;
    }

    protected final Context getContext() {
        return sContext;
    }

    @SuppressWarnings("TypeParameterUnusedInFormals") // error prone complains about returning <T>
    protected final <T> T getCarService(@NonNull String serviceName) {
        assertThat(serviceName).isNotNull();
        Object service = mCar.getCarManager(serviceName);
        assertWithMessage("Could not get service %s", serviceName).that(service).isNotNull();

        @SuppressWarnings("unchecked")
        T castService = (T) service;
        return castService;
    }

    protected static void assertMainThread() {
        assertThat(Looper.getMainLooper().isCurrentThread()).isTrue();
    }

    protected static final class DefaultServiceConnectionListener implements ServiceConnection {
        private final Semaphore mConnectionWait = new Semaphore(0);

        public void waitForConnection(long timeoutMs) throws InterruptedException {
            mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            assertMainThread();
            mConnectionWait.release();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            assertMainThread();
        }
    }

    protected static void suspendToRamAndResume(boolean disableBackgroundUsersStart)
            throws Exception {
        Log.d(TAG, "Emulate suspend to RAM and resume");
        try {
            if (disableBackgroundUsersStart) {
                runShellCommand("cmd car_service set-start-bg-users-on-garage-mode false");
            }

            PowerManager powerManager = sContext.getSystemService(PowerManager.class);
            // clear log
            runShellCommand("logcat -b all -c");
            runShellCommand("cmd car_service suspend");
            // Check for suspend success
            waitUntil("screen is still on after suspend",
                    SUSPEND_TIMEOUT_MS, () -> !powerManager.isScreenOn());

            // Force turn off garage mode
            runShellCommand("cmd car_service garage-mode off");
            runShellCommand("cmd car_service resume");
            waitForLogcatMessage("logcat -b events", "car_user_svc_initial_user_info_req_complete: "
                    + InitialUserInfoRequestType.RESUME, 60_000);
        } catch (Exception e) {
            runShellCommand("cmd car_service set-start-bg-users-on-garage-mode true");
        }
    }

    /**
     * Wait for a particular logcat message.
     *
     * @param cmd is logcat command with buffer or filters
     * @param match is the string to be found in the log
     * @param timeoutMs for which call should wait for the match
     */
    protected static void waitForLogcatMessage(String cmd, String match, int timeoutMs) {
        Log.d(TAG, "waiting for logcat match: " + match);
        long startTime = SystemClock.elapsedRealtime();
        UiAutomation automation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
        ParcelFileDescriptor output = automation.executeShellCommand(cmd);
        FileDescriptor fd = output.getFileDescriptor();
        FileInputStream fileInputStream = new FileInputStream(fd);
        try (BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(fileInputStream))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                if (line.contains(match)) {
                    Log.d(TAG, "match found in "
                            + (SystemClock.elapsedRealtime() - startTime) + " ms");
                    break;
                }
                if ((SystemClock.elapsedRealtime() - startTime) > timeoutMs) {
                    fail("match was not found, Timeout: " + timeoutMs + " ms");
                }
            }
        } catch (IOException e) {
            fail("match was not found, IO exception: " + e);
        }
    }

    protected static boolean waitUntil(String msg, long timeoutMs,
            BooleanSupplierWithThrow condition) {
        long deadline = SystemClock.elapsedRealtime() + timeoutMs;
        do {
            try {
                if (condition.getAsBoolean()) {
                    return true;
                }
            } catch (Exception e) {
                Log.e(TAG, "Exception in waitUntil: " + msg);
                throw new RuntimeException(e);
            }
            SystemClock.sleep(SMALL_NAP_MS);
        } while (SystemClock.elapsedRealtime() < deadline);

        fail(msg + " after: " + timeoutMs + "ms");
        return false;
    }

    protected void requireNonUserBuild() {
        assumeFalse("Requires Shell commands that are not available on user builds", Build.IS_USER);
    }

    protected String getTestName() {
        return getClass().getSimpleName() + "." + mTestName.getMethodName();
    }
}
