/*
 * Copyright (C) 2017 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.cluster;

import static android.car.cluster.ClusterRenderingService.LOCAL_BINDING_ACTION;
import static android.content.Intent.ACTION_USER_SWITCHED;
import static android.content.Intent.ACTION_USER_UNLOCKED;
import static android.content.PermissionChecker.PERMISSION_GRANTED;

import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.car.Car;
import android.car.cluster.navigation.NavigationState.NavigationStateProto;
import android.car.cluster.sensors.Sensors;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModelProviders;
import androidx.viewpager.widget.ViewPager;

import com.android.car.telephony.common.InMemoryPhoneBook;

import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

/**
 * Main activity displayed on the instrument cluster. This activity contains fragments for each of
 * the cluster "facets" (e.g.: navigation, communication, media and car state). Users can navigate
 * to each facet by using the steering wheel buttons.
 * <p>
 * This activity runs on "system user" (see {@link UserHandle#USER_SYSTEM}) but it is visible on
 * all users (the same activity remains active even during user switch).
 * <p>
 * This activity also launches a default navigation app inside a virtual display (which is located
 * inside {@link NavigationFragment}). This navigation app is launched when:
 * <ul>
 * <li>Virtual display for navigation apps is ready.
 * <li>After every user switch.
 * </ul>
 * This is necessary because the navigation app runs under a normal user, and different users will
 * see different instances of the same application, with their own personalized data.
 */
public class MainClusterActivity extends FragmentActivity implements
        ClusterRenderingService.ServiceClient {
    private static final String TAG = "Cluster.MainActivity";

    private static final int NAV_FACET_ID = 0;
    private static final int COMMS_FACET_ID = 1;
    private static final int MEDIA_FACET_ID = 2;
    private static final int INFO_FACET_ID = 3;

    private static final NavigationStateProto NULL_NAV_STATE =
            NavigationStateProto.getDefaultInstance();
    private static final int NO_DISPLAY = -1;

    private ViewPager mPager;
    private NavStateController mNavStateController;
    private ClusterViewModel mClusterViewModel;

    private Map<View, Facet<?>> mButtonToFacet = new HashMap<>();
    private SparseArray<Facet<?>> mOrderToFacet = new SparseArray<>();

    private Map<Sensors.Gear, View> mGearsToIcon = new HashMap<>();
    private InputMethodManager mInputMethodManager;
    private ClusterRenderingService mService;
    private VirtualDisplay mPendingVirtualDisplay = null;

    private static final int NAVIGATION_ACTIVITY_RETRY_INTERVAL_MS = 1000;
    private static final int NAVIGATION_ACTIVITY_RELAUNCH_DELAY_MS = 5000;

    private ActivityMonitor mActivityMonitor = new ActivityMonitor();
    private final Handler mHandler = new Handler();
    private final Runnable mRetryLaunchNavigationActivity = this::tryLaunchNavigationActivity;
    private VirtualDisplay mNavigationDisplay = new VirtualDisplay(NO_DISPLAY, null);

    private int mPreviousFacet = COMMS_FACET_ID;

    /**
     * Description of a virtual display
     */
    public static class VirtualDisplay {
        /** Identifier of the display */
        public final int mDisplayId;
        /** Rectangular area inside this display that can be viewed without obstructions */
        public final Rect mUnobscuredBounds;

        public VirtualDisplay(int displayId, Rect unobscuredBounds) {
            mDisplayId = displayId;
            mUnobscuredBounds = unobscuredBounds;
        }
    }

    private final View.OnFocusChangeListener mFacetButtonFocusListener =
            new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {
                        mPager.setCurrentItem(mButtonToFacet.get(v).mOrder);
                    }
                }
            };

    private ServiceConnection mClusterRenderingServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG, "onServiceConnected, name: " + name + ", service: " + service);
            mService = ((ClusterRenderingService.LocalBinder) service).getService();
            mService.registerClient(MainClusterActivity.this);
            mNavStateController.setImageResolver(mService.getImageResolver());
            if (mPendingVirtualDisplay != null) {
                // If haven't reported the virtual display yet, do so on service connect.
                reportNavDisplay(mPendingVirtualDisplay);
                mPendingVirtualDisplay = null;
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, "onServiceDisconnected, name: " + name);
            mService = null;
            mNavStateController.setImageResolver(null);
            onNavigationStateChange(NULL_NAV_STATE);
        }
    };

    private ActivityMonitor.ActivityListener mNavigationActivityMonitor = (displayId, activity) -> {
        if (displayId != mNavigationDisplay.mDisplayId) {
            return;
        }
        mClusterViewModel.setCurrentNavigationActivity(activity);
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
        setContentView(R.layout.activity_main);

        mInputMethodManager = getSystemService(InputMethodManager.class);

        Intent intent = new Intent(this, ClusterRenderingService.class);
        intent.setAction(LOCAL_BINDING_ACTION);
        bindServiceAsUser(intent, mClusterRenderingServiceConnection, 0, UserHandle.SYSTEM);

        registerFacet(new Facet<>(findViewById(R.id.btn_nav),
                NAV_FACET_ID, NavigationFragment.class));
        registerFacet(new Facet<>(findViewById(R.id.btn_phone),
                COMMS_FACET_ID, PhoneFragment.class));
        registerFacet(new Facet<>(findViewById(R.id.btn_music),
                MEDIA_FACET_ID, MusicFragment.class));
        registerFacet(new Facet<>(findViewById(R.id.btn_car_info),
                INFO_FACET_ID, CarInfoFragment.class));
        registerGear(findViewById(R.id.gear_parked), Sensors.Gear.PARK);
        registerGear(findViewById(R.id.gear_reverse), Sensors.Gear.REVERSE);
        registerGear(findViewById(R.id.gear_neutral), Sensors.Gear.NEUTRAL);
        registerGear(findViewById(R.id.gear_drive), Sensors.Gear.DRIVE);

        mPager = findViewById(R.id.pager);
        mPager.setAdapter(new ClusterPageAdapter(getSupportFragmentManager()));
        mOrderToFacet.get(NAV_FACET_ID).mButton.requestFocus();
        mNavStateController = new NavStateController(findViewById(R.id.navigation_state));

        mClusterViewModel = ViewModelProviders.of(this).get(ClusterViewModel.class);
        mClusterViewModel.getNavigationFocus().observe(this, focus -> {
            // If focus is lost, we launch the default navigation activity again.
            if (!focus) {
                mNavStateController.update(null);
                tryLaunchNavigationActivity();
            }
        });
        mClusterViewModel.getNavigationActivityState().observe(this, state -> {
            if (state == ClusterViewModel.NavigationActivityState.LOADING) {
                if (!mHandler.hasCallbacks(mRetryLaunchNavigationActivity)) {
                    mHandler.postDelayed(mRetryLaunchNavigationActivity,
                            NAVIGATION_ACTIVITY_RELAUNCH_DELAY_MS);
                }
            } else {
                mHandler.removeCallbacks(mRetryLaunchNavigationActivity);
            }
        });

        mClusterViewModel.getSensor(Sensors.SENSOR_GEAR).observe(this, this::updateSelectedGear);

        registerSensor(findViewById(R.id.info_fuel), mClusterViewModel.getFuelLevel());
        registerSensor(findViewById(R.id.info_speed), mClusterViewModel.getSpeed());
        registerSensor(findViewById(R.id.info_range), mClusterViewModel.getRange());
        registerSensor(findViewById(R.id.info_rpm), mClusterViewModel.getRPM());

        mActivityMonitor.start();

        InMemoryPhoneBook.init(this);

        PhoneFragmentViewModel phoneViewModel = ViewModelProviders.of(this).get(
                PhoneFragmentViewModel.class);

        phoneViewModel.setPhoneStateCallback(new PhoneFragmentViewModel.PhoneStateCallback() {
            @Override
            public void onCall() {
                if (mPager.getCurrentItem() != COMMS_FACET_ID) {
                    mPreviousFacet = mPager.getCurrentItem();
                }
                mOrderToFacet.get(COMMS_FACET_ID).mButton.requestFocus();
            }

            @Override
            public void onDisconnect() {
                if (mPreviousFacet != COMMS_FACET_ID) {
                    mOrderToFacet.get(mPreviousFacet).mButton.requestFocus();
                }
            }
        });
    }

    private <V> void registerSensor(TextView textView, LiveData<V> source) {
        String emptyValue = getString(R.string.info_value_empty);
        source.observe(this, value -> textView.setText(value != null
                ? value.toString() : emptyValue));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
        mActivityMonitor.stop();
        if (mService != null) {
            mService.unregisterClient(this);
            mService = null;
        }
        unbindService(mClusterRenderingServiceConnection);
    }

    @Override
    public void onKeyEvent(KeyEvent event) {
        Log.i(TAG, "onKeyEvent, event: " + event);

        // This is a hack. We use SOURCE_CLASS_POINTER here because this type of input is associated
        // with the display. otherwise this event will be ignored in ViewRootImpl because injecting
        // KeyEvent w/o activity being focused is useless.
        event.setSource(event.getSource() | InputDevice.SOURCE_CLASS_POINTER);
        mInputMethodManager.dispatchKeyEventFromInputMethod(getCurrentFocus(), event);
    }

    @Override
    public void onNavigationStateChange(NavigationStateProto state) {
        Log.d(TAG, "onNavigationStateChange: " + state);
        if (mNavStateController != null) {
            mNavStateController.update(state);
        }
    }

    public void updateNavDisplay(VirtualDisplay virtualDisplay) {
        // Starting the default navigation activity. This activity will be shown when navigation
        // focus is not taken.
        startNavigationActivity(virtualDisplay);
        // Notify the service (so it updates display properties on car service)
        if (mService == null) {
            // Service is not bound yet. Hold the information and notify when the service is bound.
            mPendingVirtualDisplay = virtualDisplay;
            return;
        } else {
            reportNavDisplay(virtualDisplay);
        }
    }

    private void reportNavDisplay(VirtualDisplay virtualDisplay) {
        mService.setActivityLaunchOptions(virtualDisplay.mDisplayId, ClusterActivityState
                .create(virtualDisplay.mDisplayId != Display.INVALID_DISPLAY,
                        virtualDisplay.mUnobscuredBounds));
    }

    public class ClusterPageAdapter extends FragmentPagerAdapter {
        public ClusterPageAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return mButtonToFacet.size();
        }

        @Override
        public Fragment getItem(int position) {
            return mOrderToFacet.get(position).getOrCreateFragment();
        }
    }

    private <T> void registerFacet(Facet<T> facet) {
        mOrderToFacet.append(facet.mOrder, facet);
        mButtonToFacet.put(facet.mButton, facet);

        facet.mButton.setOnFocusChangeListener(mFacetButtonFocusListener);
    }

    private static class Facet<T> {
        Button mButton;
        Class<T> mClazz;
        int mOrder;

        Facet(Button button, int order, Class<T> clazz) {
            this.mButton = button;
            this.mOrder = order;
            this.mClazz = clazz;
        }

        private Fragment mFragment;

        Fragment getOrCreateFragment() {
            if (mFragment == null) {
                try {
                    mFragment = (Fragment) mClazz.getConstructors()[0].newInstance();
                } catch (InstantiationException | IllegalAccessException
                        | InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            }
            return mFragment;
        }
    }

    private void startNavigationActivity(VirtualDisplay virtualDisplay) {
        mActivityMonitor.removeListener(mNavigationDisplay.mDisplayId, mNavigationActivityMonitor);
        mActivityMonitor.addListener(virtualDisplay.mDisplayId, mNavigationActivityMonitor);
        mNavigationDisplay = virtualDisplay;
        tryLaunchNavigationActivity();
    }

    /**
     * Tries to start a default navigation activity in the cluster. During system initialization
     * launching user activities might fail due the system not being ready or {@link PackageManager}
     * not being able to resolve the implicit intent. It is also possible that the system doesn't
     * have a default navigation activity selected yet.
     */
    private void tryLaunchNavigationActivity() {
        if (mNavigationDisplay.mDisplayId == NO_DISPLAY) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, String.format("Launch activity ignored (no display yet)"));
            }
            // Not ready to launch yet.
            return;
        }
        mHandler.removeCallbacks(mRetryLaunchNavigationActivity);

        ComponentName navigationActivity = getNavigationActivity(this);
        mClusterViewModel.setFreeNavigationActivity(navigationActivity);

        try {
            if (navigationActivity == null) {
                throw new ActivityNotFoundException();
            }
            ClusterActivityState activityState = ClusterActivityState
                    .create(true, mNavigationDisplay.mUnobscuredBounds);
            Intent intent = new Intent(Intent.ACTION_MAIN)
                    .setComponent(navigationActivity)
                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .putExtra(CarInstrumentClusterManager.KEY_EXTRA_ACTIVITY_STATE,
                            activityState.toBundle());

            Log.d(TAG, "Launching: " + intent + " on display: " + mNavigationDisplay.mDisplayId);
            Bundle activityOptions = ActivityOptions.makeBasic()
                    .setLaunchDisplayId(mNavigationDisplay.mDisplayId)
                    .toBundle();

            startActivityAsUser(intent, activityOptions, UserHandle.CURRENT);
        } catch (ActivityNotFoundException ex) {
            // Some activities might not be available right on startup. We will retry.
            mHandler.postDelayed(mRetryLaunchNavigationActivity,
                    NAVIGATION_ACTIVITY_RETRY_INTERVAL_MS);
        } catch (Exception ex) {
            Log.e(TAG, "Unable to start navigation activity: " + navigationActivity, ex);
        }
    }

    /**
     * Returns a default navigation activity to show in the cluster.
     * In the current implementation we obtain this activity from an intent defined in a resources
     * file (which OEMs can overlay).
     * Alternatively, other implementations could:
     * <ul>
     * <li>Dynamically detect what's the default navigation activity the user has selected on the
     * head unit, and obtain the activity marked with
     * {@link CarInstrumentClusterManager#CATEGORY_NAVIGATION} from the same package.
     * <li>Let the user select one from settings.
     * </ul>
     */
    static ComponentName getNavigationActivity(Context context) {
        PackageManager pm = context.getPackageManager();
        int userId = ActivityManager.getCurrentUser();
        String intentString = context.getString(R.string.freeNavigationIntent);

        if (intentString == null) {
            Log.w(TAG, "No free navigation activity defined");
            return null;
        }
        Log.i(TAG, "Free navigation intent: " + intentString);

        try {
            Intent intent = Intent.parseUri(intentString, Intent.URI_INTENT_SCHEME);
            ResolveInfo navigationApp = pm.resolveActivityAsUser(intent,
                    PackageManager.MATCH_DEFAULT_ONLY, userId);
            if (navigationApp == null) {
                return null;
            }

            // Check that it has the right permissions
            if (pm.checkPermission(Car.PERMISSION_CAR_DISPLAY_IN_CLUSTER, navigationApp.activityInfo
                    .packageName) != PERMISSION_GRANTED) {
                Log.i(TAG, String.format("Package '%s' doesn't have permission %s",
                        navigationApp.activityInfo.packageName,
                        Car.PERMISSION_CAR_DISPLAY_IN_CLUSTER));
                return null;
            }

            return new ComponentName(navigationApp.activityInfo.packageName,
                    navigationApp.activityInfo.name);
        } catch (URISyntaxException ex) {
            Log.e(TAG, "Unable to parse free navigation activity intent: '" + intentString + "'");
            return null;
        }
    }

    private void registerGear(View view, Sensors.Gear gear) {
        mGearsToIcon.put(gear, view);
    }

    private void updateSelectedGear(Sensors.Gear gear) {
        for (Map.Entry<Sensors.Gear, View> entry : mGearsToIcon.entrySet()) {
            entry.getValue().setSelected(entry.getKey() == gear);
        }
    }
}
