package jp.sourceforge.nicoro;

import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.test.ActivityInstrumentationTestCase2;

public abstract class AbstractListMenuFragmentBodyUnitTest extends ActivityInstrumentationTestCase2<ListMenuActivity> {
    protected Instrumentation mInstr;
    protected Context mContext;

    private ListMenuActivity mActivity;

    @SuppressWarnings("deprecation")
    public AbstractListMenuFragmentBodyUnitTest(Class<ListMenuActivity> activityClass) {
        super("jp.sourceforge.nicoro", activityClass);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mInstr = getInstrumentation();
        mContext = mInstr.getTargetContext();
    }

    @Override
    protected void tearDown() throws Exception {
        if (mActivity != null) {
            mActivity.finish();
            mActivity = null;
            mInstr.waitForIdleSync();
        }
        mInstr = null;
        mContext = null;
        super.tearDown();
    }

    protected void commonTestOnCreate(final int radioId,
            final Class<? extends Fragment> fragmentClass) throws Throwable {
        mActivity = startActivity(null, radioId);
        waitFragment(fragmentClass);
    }

    protected void commonTestOnCreateSavedInstanceStateAnyItem(final int radioId,
            final Class<? extends Fragment> fragmentClass) throws Throwable {
        // FIXME Fragmentの都合でテストが通らなくなっているのでいったん没
//        final Bundle savedInstanceState = new Bundle();
//        runTestOnUiThread(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    mActivity = startActivity(null, radioId);
//                } catch (RuntimeException e) {
//                    throw e;
//                } catch (Exception e) {
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//        callActivityOnStart();
//        callActivityOnResume();
//        Fragment fragment = ViewUtil.findFragmentByTag(
//                mActivity.getSupportFragmentManager(),
//                fragmentTag);
//        assertNotNull(fragment);
//        callActivityOnPause();
//        callActivityOnSaveInstanceState(savedInstanceState);
//        callActivityOnStop();
//        callActivityOnDestroy();
//
//        callActivityOnCreate(savedInstanceState);
//        callActivityOnStart();
//        callActivityOnResume();
//        fragment = ViewUtil.findFragmentByTag(
//                mActivity.getSupportFragmentManager(),
//                fragmentTag);
//        assertNotNull(fragment);
//        callActivityOnPause();
//        callActivityOnSaveInstanceState(savedInstanceState);
//        callActivityOnStop();
//        callActivityOnDestroy();
    }

    protected ListMenuActivity startActivity(
            Bundle savedInstanceState, int radioId) throws Exception {
        Intent intent = new Intent(mContext, ListMenuActivity.class);
        intent.putExtra(ListMenuActivity.INTENT_EXTRA_DEFAULT_LIST_RADIO,
                radioId);
        setActivityIntent(intent);
        return getActivity();
    }

    private void waitFragment(final Class<? extends Fragment> classFragment) {
        TestUtil.assertUntil(new TestUtil.Until() {
            private Fragment f;

            @Override
            public String errorMessage() {
                return "Wait: " + classFragment.getSimpleName()
                    + " but Current: " + (f == null ? mActivity.getSupportFragmentManager().findFragmentById(R.id.fragment_list) : f.toString());
            }

            @Override
            public boolean command() {
                f = mActivity.findFragmentInListMenu(classFragment);
                if (f == null) {
                    return false;
                }
                if (f.getClass() != classFragment) {
                    return false;
                }
                if (f.getId() != R.id.fragment_list) {
                    return false;
                }
                return f.isVisible();
            }
        });
    }
}
