/*
 * 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.testing;

import static org.junit.Assert.assertNotNull;

import android.annotation.Nullable;
import android.app.Fragment;
import android.app.FragmentController;
import android.app.FragmentHostCallback;
import android.app.FragmentManagerNonConfig;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Parcelable;
import android.support.test.InstrumentationRegistry;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;

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

import java.io.FileDescriptor;
import java.io.PrintWriter;

/**
 * Base class for fragment class tests.  Just adding one for any fragment will push it through
 * general lifecycle events and ensure no basic leaks are happening.  This class also implements
 * the host for subclasses, so they can push it into desired states and do any unit testing
 * required.
 */
public abstract class BaseFragmentTest {

    private static final int VIEW_ID = 42;
    private final Class<? extends Fragment> mCls;
    private Handler mHandler;
    protected FrameLayout mView;
    protected FragmentController mFragments;
    protected Fragment mFragment;

    @Rule
    public final TestableContext mContext = getContext();

    public BaseFragmentTest(Class<? extends Fragment> cls) {
        mCls = cls;
    }

    protected void createRootView() {
        mView = new FrameLayout(mContext);
    }

    @Before
    public void setupFragment() throws Exception {
        createRootView();
        mView.setId(VIEW_ID);

        assertNotNull("BaseFragmentTest must be tagged with @RunWithLooper",
                TestableLooper.get(this));
        TestableLooper.get(this).runWithLooper(() -> {
            mHandler = new Handler();

            mFragment = mCls.newInstance();
            mFragments = FragmentController.createController(new HostCallbacks());
            mFragments.attachHost(null);
            mFragments.getFragmentManager().beginTransaction()
                    .replace(VIEW_ID, mFragment)
                    .commit();
        });
    }

    /**
     * Allows tests to sub-class TestableContext if they want to provide any extended functionality
     * or provide a {@link LeakCheck} to the TestableContext upon instantiation.
     */
    protected TestableContext getContext() {
        return new TestableContext(InstrumentationRegistry.getContext());
    }

    @After
    public void tearDown() throws Exception {
        if (mFragments != null) {
            // Set mFragments to null to let it know not to destroy.
            TestableLooper.get(this).runWithLooper(() -> mFragments.dispatchDestroy());
        }
    }

    @Test
    public void testCreateDestroy() {
        mFragments.dispatchCreate();
        processAllMessages();
        destroyFragments();
    }

    @Test
    public void testStartStop() {
        mFragments.dispatchStart();
        processAllMessages();
        mFragments.dispatchStop();
        processAllMessages();
    }

    @Test
    public void testResumePause() {
        mFragments.dispatchResume();
        processAllMessages();
        mFragments.dispatchPause();
        processAllMessages();
    }

    @Test
    public void testAttachDetach() {
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
                LayoutParams.TYPE_SYSTEM_ALERT,
                0, PixelFormat.TRANSLUCENT);
        mFragments.dispatchResume();
        processAllMessages();
        attachFragmentToWindow();
        detachFragmentToWindow();
        mFragments.dispatchPause();
        processAllMessages();
    }

    @Test
    public void testRecreate() {
        mFragments.dispatchResume();
        processAllMessages();
        recreateFragment();
        processAllMessages();
    }

    @Test
    public void testMultipleResumes() {
        mFragments.dispatchResume();
        processAllMessages();
        mFragments.dispatchStop();
        processAllMessages();
        mFragments.dispatchResume();
        processAllMessages();
    }

    protected void recreateFragment() {
        mFragments.dispatchPause();
        Parcelable p = mFragments.saveAllState();
        mFragments.dispatchDestroy();

        mFragments = FragmentController.createController(new HostCallbacks());
        mFragments.attachHost(null);
        mFragments.restoreAllState(p, (FragmentManagerNonConfig) null);
        mFragments.dispatchResume();
        mFragment = mFragments.getFragmentManager().findFragmentById(VIEW_ID);
    }

    protected void attachFragmentToWindow() {
        ViewUtils.attachView(mView);
        TestableLooper.get(this).processAllMessages();
    }

    protected void detachFragmentToWindow() {
        ViewUtils.detachView(mView);
        TestableLooper.get(this).processAllMessages();
    }

    protected void destroyFragments() {
        mFragments.dispatchDestroy();
        processAllMessages();
        mFragments = null;
    }

    protected void processAllMessages() {
        TestableLooper.get(this).processAllMessages();
    }

    private View findViewById(int id) {
        return mView.findViewById(id);
    }

    private class HostCallbacks extends FragmentHostCallback<BaseFragmentTest> {
        public HostCallbacks() {
            super(mContext, BaseFragmentTest.this.mHandler, 0);
        }

        @Override
        public BaseFragmentTest onGetHost() {
            return BaseFragmentTest.this;
        }

        @Override
        public void onDump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
        }

        @Override
        public boolean onShouldSaveFragmentState(Fragment fragment) {
            return true; // True for now.
        }

        @Override
        public LayoutInflater onGetLayoutInflater() {
            return LayoutInflater.from(mContext);
        }

        @Override
        public boolean onUseFragmentManagerInflaterFactory() {
            return true;
        }

        @Override
        public boolean onHasWindowAnimations() {
            return false;
        }

        @Override
        public int onGetWindowAnimations() {
            return 0;
        }

        @Override
        public void onAttachFragment(Fragment fragment) {
        }

        @Nullable
        @Override
        public View onFindViewById(int id) {
            return BaseFragmentTest.this.findViewById(id);
        }

        @Override
        public boolean onHasView() {
            return true;
        }
    }
}
