/*
 * 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 com.android.launcher3.states;

import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;

import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.MainThreadExecutor;

import java.lang.ref.WeakReference;

/**
 * Utility class to sending state handling logic to Launcher from within the same process.
 *
 * Extending {@link Binder} ensures that the platform maintains a single instance of each object
 * which allows this object to safely navigate the system process.
 */
public abstract class InternalStateHandler extends Binder {

    public static final String EXTRA_STATE_HANDLER = "launcher.state_handler";

    private static final Scheduler sScheduler = new Scheduler();

    /**
     * Initializes the handler when the launcher is ready.
     * @return true if the handler wants to stay alive.
     */
    protected abstract boolean init(Launcher launcher, boolean alreadyOnHome);

    public final Intent addToIntent(Intent intent) {
        Bundle extras = new Bundle();
        extras.putBinder(EXTRA_STATE_HANDLER, this);
        intent.putExtras(extras);
        return intent;
    }

    public final void initWhenReady() {
        sScheduler.schedule(this);
    }

    public boolean clearReference() {
        return sScheduler.clearReference(this);
    }

    public static boolean hasPending() {
        return sScheduler.hasPending();
    }

    public static boolean handleCreate(Launcher launcher, Intent intent) {
        return handleIntent(launcher, intent, false, false);
    }

    public static boolean handleNewIntent(Launcher launcher, Intent intent, boolean alreadyOnHome) {
        return handleIntent(launcher, intent, alreadyOnHome, true);
    }

    private static boolean handleIntent(
            Launcher launcher, Intent intent, boolean alreadyOnHome, boolean explicitIntent) {
        boolean result = false;
        if (intent != null && intent.getExtras() != null) {
            IBinder stateBinder = intent.getExtras().getBinder(EXTRA_STATE_HANDLER);
            if (stateBinder instanceof InternalStateHandler) {
                InternalStateHandler handler = (InternalStateHandler) stateBinder;
                if (!handler.init(launcher, alreadyOnHome)) {
                    intent.getExtras().remove(EXTRA_STATE_HANDLER);
                }
                result = true;
            }
        }
        if (!result && !explicitIntent) {
            result = sScheduler.initIfPending(launcher, alreadyOnHome);
        }
        return result;
    }

    private static class Scheduler implements Runnable {

        private WeakReference<InternalStateHandler> mPendingHandler = new WeakReference<>(null);
        private MainThreadExecutor mMainThreadExecutor;

        public void schedule(InternalStateHandler handler) {
            synchronized (this) {
                mPendingHandler = new WeakReference<>(handler);
                if (mMainThreadExecutor == null) {
                    mMainThreadExecutor = new MainThreadExecutor();
                }
            }
            mMainThreadExecutor.execute(this);
        }

        @Override
        public void run() {
            LauncherAppState app = LauncherAppState.getInstanceNoCreate();
            if (app == null) {
                return;
            }
            Callbacks cb = app.getModel().getCallback();
            if (!(cb instanceof Launcher)) {
                return;
            }
            Launcher launcher = (Launcher) cb;
            initIfPending(launcher, launcher.isStarted());
        }

        public boolean initIfPending(Launcher launcher, boolean alreadyOnHome) {
            InternalStateHandler pendingHandler = mPendingHandler.get();
            if (pendingHandler != null) {
                if (!pendingHandler.init(launcher, alreadyOnHome)) {
                    clearReference(pendingHandler);
                }
                return true;
            }
            return false;
        }

        public boolean clearReference(InternalStateHandler handler) {
            synchronized (this) {
                if (mPendingHandler.get() == handler) {
                    mPendingHandler.clear();
                    return true;
                }
                return false;
            }
        }

        public boolean hasPending() {
            return mPendingHandler.get() != null;
        }
    }
}