/*
 * Copyright (C) 2015 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.cts.verifier;

import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.cts.verifier.R;

/**
 * Test list activity that supports showing dialogs with pass/fail buttons instead of
 * starting new activities.
 * In addition to that dialogs have a 'go' button that can be configured to launch an intent.
 * Instructions are shown on top of the screen and a test preparation button is provided.
 */
public abstract class DialogTestListActivity extends PassFailButtons.TestListActivity {
    private final int mLayoutId;
    private final int mTitleStringId;
    private final int mInfoStringId;
    private final int mInstructionsStringId;

    protected Button mPrepareTestButton;

    protected int mCurrentTestPosition;

    protected DialogTestListActivity(int layoutId, int titleStringId, int infoStringId,
            int instructionsStringId) {
        mLayoutId = layoutId;
        mTitleStringId = titleStringId;
        mInfoStringId = infoStringId;
        mInstructionsStringId = instructionsStringId;
    }

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

        setContentView(mLayoutId);
        setInfoResources(mTitleStringId, mInfoStringId, -1);
        setPassFailButtonClickListeners();
        getPassButton().setEnabled(false);
        setResult(RESULT_CANCELED);

        ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);

        setupTests(adapter);

        adapter.registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                updatePassButton();
            }
        });

        setTestListAdapter(adapter);

        mCurrentTestPosition = 0;

        TextView instructionTextView = (TextView)findViewById(R.id.test_instructions);
        instructionTextView.setText(mInstructionsStringId);
        mPrepareTestButton = (Button)findViewById(R.id.prepare_test_button);
    }

    /**
     * Subclasses must add their tests items to the provided adapter(usually instances of
     * {@link DialogTestListItem} or {@link DialogTestListItemWithIcon} but any class deriving from
     * {@link TestListAdapter.TestListItem} will do).
     * @param adapter The adapter to add test items to.
     */
    protected abstract void setupTests(ArrayTestListAdapter adapter);

    // Enable Pass Button when all tests passed.
    private void updatePassButton() {
        getPassButton().setEnabled(mAdapter.allTestsPassed());
    }

    public class DefaultTestCallback implements DialogTestListItem.TestCallback {
        final private DialogTestListItem mTest;

        public DefaultTestCallback(DialogTestListItem test) {
            mTest = test;
        }

        @Override
        public void onPass() {
            clearRemainingState(mTest);
            setTestResult(mTest, TestResult.TEST_RESULT_PASSED);
        }

        @Override
        public void onFail() {
            clearRemainingState(mTest);
            setTestResult(mTest, TestResult.TEST_RESULT_FAILED);
        }
    }

    public void showManualTestDialog(final DialogTestListItem test) {
        showManualTestDialog(test, new DefaultTestCallback(test));
    }

    public void showManualTestDialog(final DialogTestListItem test,
            final DialogTestListItem.TestCallback callback) {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this)
                .setIcon(android.R.drawable.ic_dialog_info)
                .setTitle(mTitleStringId)
                .setNeutralButton(R.string.go_button_text, null)
                .setPositiveButton(R.string.pass_button_text, new AlertDialog.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        callback.onPass();
                    }
                })
                .setNegativeButton(R.string.fail_button_text, new AlertDialog.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        callback.onFail();
                    }
                });
        View customView = test.getCustomView();
        if (customView != null) {
            dialogBuilder.setView(customView);
        } else {
            dialogBuilder.setMessage(test.getManualTestInstruction());
        }
        final AlertDialog dialog = dialogBuilder.show();
        // Note: Setting the OnClickListener on the Dialog rather than the Builder, prevents the
        // dialog being dismissed on onClick.
        dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!startTestIntent(test)) {
                    dialog.dismiss();
                }
            }
        });
    }

    @Override
    protected void handleItemClick(ListView l, View v, int position, long id) {
        TestListAdapter.TestListItem test = (TestListAdapter.TestListItem) getListAdapter()
                .getItem(position);
        if (test instanceof DialogTestListItem) {
            mCurrentTestPosition = position;
            ((DialogTestListItem)test).performTest(this);
        } else {
            super.handleItemClick(l, v, position, id);
        }
    }


    /**
     * Start a test's manual intent
     * @param test The test the manual intent of which is to be started.
     * @return true if activity could be started successfully, false otherwise.
     */
    boolean startTestIntent(final DialogTestListItem test) {
        final Intent intent = test.intent;
        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, "Cannot start " + intent, Toast.LENGTH_LONG).show();
            setTestResult(test, TestResult.TEST_RESULT_FAILED);
            return false;
        }
        return true;
    }

    protected void clearRemainingState(final DialogTestListItem test) {
        // do nothing, override in subclass if needed
    }

    protected void setTestResult(DialogTestListItem test, int result) {
        // Bundle result in an intent to feed into handleLaunchTestResult
        Intent resultIntent = new Intent();
        TestResult.addResultData(resultIntent, result, test.testName, /* testDetails */ null,
                /* reportLog */ null);
        handleLaunchTestResult(RESULT_OK, resultIntent);
        getListView().smoothScrollToPosition(mCurrentTestPosition + 1);
    }

    protected void showToast(int messageId) {
        String message = getString(messageId);
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

    protected static class DialogTestListItem extends TestListAdapter.TestListItem {

        public interface TestCallback {
            void onPass();
            void onFail();
        }

        private String mManualInstruction;

        public DialogTestListItem(Context context, int nameResId, String testId) {
            super(context.getString(nameResId), testId, null, null, null, null);
        }

        public DialogTestListItem(Context context, int nameResId, String testId,
                int testInstructionResId, Intent testIntent) {
            super(context.getString(nameResId), testId, testIntent, null, null, null);
            mManualInstruction = context.getString(testInstructionResId);
        }

        public void performTest(DialogTestListActivity activity) {
            activity.showManualTestDialog(this);
        }

        public String getManualTestInstruction() {
            return mManualInstruction;
        }

        public Intent getManualTestIntent() {
            return intent;
        }

        public View getCustomView() {
            return null;
        }

        @Override
        boolean isTest() {
            return true;
        }
    }

    protected static class DialogTestListItemWithIcon extends DialogTestListItem {

        private final int mImageResId;
        private final Context mContext;

        public DialogTestListItemWithIcon(Context context, int nameResId, String testId,
                int testInstructionResId, Intent testIntent, int imageResId) {
            super(context, nameResId, testId, testInstructionResId, testIntent);
            mContext = context;
            mImageResId = imageResId;
        }

        @Override
        public View getCustomView() {
            LayoutInflater layoutInflater = LayoutInflater.from(mContext);
            View view = layoutInflater.inflate(R.layout.dialog_custom_view,
                    null /* root */);
            ((ImageView) view.findViewById(R.id.sample_icon)).setImageResource(mImageResId);
            ((TextView) view.findViewById(R.id.message)).setText(getManualTestInstruction());
            return view;
        }
    }
}
