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

import static android.widget.ArrayAdapter.createFromResource;

import static com.google.common.truth.Truth.assertWithMessage;

import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Activity that has the following fields:
 *
 * <ul>
 *   <li>Credit Card Number EditText (id: cc_numberusername, no input-type)
 *   <li>Credit Card Expiration EditText (id: cc_expiration, no input-type)
 *   <li>Address RadioGroup (id: addess, no autofill-type)
 *   <li>Save Credit Card CheckBox (id: save_cc, no autofill-type)
 *   <li>Clear Button
 *   <li>Buy Button
 * </ul>
 */
public class CheckoutActivity extends AbstractAutoFillActivity {
    private static final long BUY_TIMEOUT_MS = 1000;

    static final String ID_CC_NUMBER = "cc_number";
    static final String ID_CC_EXPIRATION = "cc_expiration";
    static final String ID_ADDRESS = "address";
    static final String ID_HOME_ADDRESS = "home_address";
    static final String ID_WORK_ADDRESS = "work_address";
    static final String ID_SAVE_CC = "save_cc";

    static final int INDEX_ADDRESS_HOME = 0;
    static final int INDEX_ADDRESS_WORK = 1;

    static final int INDEX_CC_EXPIRATION_YESTERDAY = 0;
    static final int INDEX_CC_EXPIRATION_TODAY = 1;
    static final int INDEX_CC_EXPIRATION_TOMORROW = 2;
    static final int INDEX_CC_EXPIRATION_NEVER = 3;

    private EditText mCcNumber;
    private Spinner mCcExpiration;
    private ArrayAdapter<CharSequence> mCcExpirationAdapter;
    private RadioGroup mAddress;
    private RadioButton mHomeAddress;
    private CheckBox mSaveCc;
    private Button mBuyButton;
    private Button mClearButton;

    private FillExpectation mExpectation;
    private CountDownLatch mBuyLatch;

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

        setContentView(getContentView());

        mCcNumber = (EditText) findViewById(R.id.cc_number);
        mCcExpiration = (Spinner) findViewById(R.id.cc_expiration);
        mAddress = (RadioGroup) findViewById(R.id.address);
        mHomeAddress = (RadioButton ) findViewById(R.id.home_address);
        mSaveCc = (CheckBox) findViewById(R.id.save_cc);
        mBuyButton = (Button) findViewById(R.id.buy);
        mClearButton = (Button) findViewById(R.id.clear);

        mCcExpirationAdapter = createFromResource(this,
                R.array.cc_expiration_values, android.R.layout.simple_spinner_item);
        mCcExpirationAdapter
                .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mCcExpiration.setAdapter(mCcExpirationAdapter);

        mBuyButton.setOnClickListener((v) -> buy());
        mClearButton.setOnClickListener((v) -> resetFields());
    }

    protected int getContentView() {
        return R.layout.checkout_activity;
    }

    /**
     * Resets the values of the input fields.
     */
    private void resetFields() {
        mCcNumber.setText("");
        mCcExpiration.setSelection(0, false);
        mAddress.clearCheck();
        mSaveCc.setChecked(false);
    }

    /**
     * Emulates a buy action.
     */
    private void buy() {
        final Intent intent = new Intent(this, WelcomeActivity.class);
        intent.putExtra(WelcomeActivity.EXTRA_MESSAGE, "Thank you an come again!");
        startActivity(intent);
        if (mBuyLatch != null) {
            // Latch is not set when activity launched outside tests
            mBuyLatch.countDown();
        }
        finish();
    }

    /**
     * Sets the expectation for an auto-fill request, so it can be asserted through
     * {@link #assertAutoFilled()} later.
     */
    void expectAutoFill(String ccNumber, int ccExpirationIndex, int addressId, boolean saveCc) {
        mExpectation = new FillExpectation(ccNumber, ccExpirationIndex, addressId, saveCc);
        mCcNumber.addTextChangedListener(mExpectation.ccNumberWatcher);
        mCcExpiration.setOnItemSelectedListener(mExpectation.ccExpirationListener);
        mAddress.setOnCheckedChangeListener(mExpectation.addressListener);
        mSaveCc.setOnCheckedChangeListener(mExpectation.saveCcListener);
    }

    /**
     * Asserts the activity was auto-filled with the values passed to
     * {@link #expectAutoFill(String, int, int, boolean)}.
     */
    void assertAutoFilled() throws Exception {
        assertWithMessage("expectAutoFill() not called").that(mExpectation).isNotNull();
        mExpectation.ccNumberWatcher.assertAutoFilled();
        mExpectation.ccExpirationListener.assertAutoFilled();
        mExpectation.addressListener.assertAutoFilled();
        mExpectation.saveCcListener.assertAutoFilled();
    }

    /**
     * Visits the {@code ccNumber} in the UiThread.
     */
    void onCcNumber(Visitor<EditText> v) {
        syncRunOnUiThread(() -> v.visit(mCcNumber));
    }

    /**
     * Visits the {@code ccExpirationDate} in the UiThread.
     */
    void onCcExpiration(Visitor<Spinner> v) {
        syncRunOnUiThread(() -> v.visit(mCcExpiration));
    }

    /**
     * Visits the {@code ccExpirationDate} adapter in the UiThread.
     */
    void onCcExpirationAdapter(Visitor<ArrayAdapter<CharSequence>> v) {
        syncRunOnUiThread(() -> v.visit(mCcExpirationAdapter));
    }

    /**
     * Visits the {@code address} in the UiThread.
     */
    void onAddress(Visitor<RadioGroup> v) {
        syncRunOnUiThread(() -> v.visit(mAddress));
    }

    /**
     * Visits the {@code homeAddress} in the UiThread.
     */
    void onHomeAddress(Visitor<RadioButton> v) {
        syncRunOnUiThread(() -> v.visit(mHomeAddress));
    }

    /**
     * Visits the {@code saveCC} in the UiThread.
     */
    void onSaveCc(Visitor<CheckBox> v) {
        syncRunOnUiThread(() -> v.visit(mSaveCc));
    }

    /**
     * Taps the buy button in the UI thread.
     */
    void tapBuy() throws Exception {
        mBuyLatch = new CountDownLatch(1);
        syncRunOnUiThread(() -> mBuyButton.performClick());
        boolean called = mBuyLatch.await(BUY_TIMEOUT_MS, TimeUnit.MILLISECONDS);
        assertWithMessage("Timeout (%s ms) waiting for buy action", BUY_TIMEOUT_MS)
                .that(called).isTrue();
    }

    /**
     * Holder for the expected auto-fill values.
     */
    private final class FillExpectation {
        private final OneTimeTextWatcher ccNumberWatcher;
        private final OneTimeSpinnerListener ccExpirationListener;
        private final OneTimeRadioGroupListener addressListener;
        private final OneTimeCompoundButtonListener saveCcListener;

        private FillExpectation(String ccNumber, int ccExpirationIndex, int addressId,
                boolean saveCc) {
            this.ccNumberWatcher = new OneTimeTextWatcher("ccNumber", mCcNumber, ccNumber);
            this.ccExpirationListener =
                    new OneTimeSpinnerListener("ccExpiration", mCcExpiration, ccExpirationIndex);
            addressListener = new OneTimeRadioGroupListener("address", mAddress, addressId);
            saveCcListener = new OneTimeCompoundButtonListener("saveCc", mSaveCc, saveCc);
        }
    }
}
