/*
 * Copyright 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.car.calendar;

import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.android.car.calendar.common.CalendarFormatter;
import com.android.car.calendar.common.Dialer;
import com.android.car.calendar.common.Navigator;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

import java.time.Clock;
import java.util.Collection;
import java.util.Locale;

/** The main Activity for the Car Calendar App. */
public class CarCalendarActivity extends FragmentActivity {
    private static final String TAG = "CarCalendarActivity";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private final Multimap<String, Runnable> mPermissionToCallbacks = HashMultimap.create();

    // Allows tests to replace certain dependencies.
    @VisibleForTesting Dependencies mDependencies;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        maybeEnableStrictMode();

        // Tests can set fake dependencies before onCreate.
        if (mDependencies == null) {
            mDependencies = new Dependencies(
                    Locale.getDefault(), Clock.systemDefaultZone(), getContentResolver());
        }

        CarCalendarViewModel carCalendarViewModel =
                new ViewModelProvider(
                                this,
                                new CarCalendarViewModelFactory(
                                        mDependencies.mResolver,
                                        mDependencies.mLocale,
                                        mDependencies.mClock))
                        .get(CarCalendarViewModel.class);

        CarCalendarView carCalendarView =
                new CarCalendarView(
                        this,
                        carCalendarViewModel,
                        new Navigator(this),
                        new Dialer(this),
                        new CalendarFormatter(
                                this.getApplicationContext(),
                                mDependencies.mLocale,
                                mDependencies.mClock));

        carCalendarView.show();
    }

    private void maybeEnableStrictMode() {
        if (DEBUG) {
            Log.i(TAG, "Enabling strict mode");
            StrictMode.setThreadPolicy(
                    new StrictMode.ThreadPolicy.Builder()
                            .detectAll()
                            .penaltyLog()
                            .penaltyDeath()
                            .build());
            StrictMode.setVmPolicy(
                    new StrictMode.VmPolicy.Builder()
                            .detectAll()
                            .penaltyLog()
                            .penaltyDeath()
                            .build());
        }
    }

    /**
     * Calls the given runnable only if the required permission is granted.
     *
     * <p>If the permission is already granted then the runnable is called immediately. Otherwise
     * the runnable is retained and the permission is requested. If the permission is granted the
     * runnable will be called otherwise it will be discarded.
     */
    void runWithPermission(String permission, Runnable runnable) {
        if (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) {
            // Run immediately if we already have permission.
            if (DEBUG) Log.d(TAG, "Running with " + permission);
            runnable.run();
        } else {
            // Keep the runnable until the permission is granted.
            if (DEBUG) Log.d(TAG, "Waiting for " + permission);
            mPermissionToCallbacks.put(permission, runnable);
            requestPermissions(new String[] {permission}, /* requestCode= */ 0);
        }
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        for (int i = 0; i < permissions.length; i++) {
            String permission = permissions[i];
            int grantResult = grantResults[i];
            Collection<Runnable> callbacks = mPermissionToCallbacks.removeAll(permission);
            if (grantResult == PackageManager.PERMISSION_GRANTED) {
                Log.e(TAG, "Permission " + permission + " granted");
                callbacks.forEach(Runnable::run);
            } else {
                // TODO(jdp) Also allow a denied runnable.
                Log.e(TAG, "Permission " + permission + " not granted");
            }
        }
    }

    private static class CarCalendarViewModelFactory implements ViewModelProvider.Factory {
        private final ContentResolver mResolver;
        private final Locale mLocale;
        private final Clock mClock;

        CarCalendarViewModelFactory(ContentResolver resolver, Locale locale, Clock clock) {
            mResolver = resolver;
            mLocale = locale;
            mClock = clock;
        }

        @SuppressWarnings("unchecked")
        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> aClass) {
            return (T) new CarCalendarViewModel(mResolver, mLocale, mClock);
        }
    }

    static class Dependencies {
        private final Locale mLocale;
        private final Clock mClock;
        private final ContentResolver mResolver;

        Dependencies(Locale locale, Clock clock, ContentResolver resolver) {
            mLocale = locale;
            mClock = clock;
            mResolver = resolver;
        }
    }
}
