/*
 * Copyright (C) 2016 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.settings.dashboard;

import android.accounts.Account;
import android.annotation.DrawableRes;
import android.annotation.LayoutRes;
import android.annotation.StringRes;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.DialogFragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

import com.android.internal.logging.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.overlay.SupportFeatureProvider;
import com.android.settings.support.SupportDisclaimerDialogFragment;
import com.android.settings.support.SupportPhone;
import com.android.settings.support.SupportPhoneDialogFragment;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.android.settings.overlay.SupportFeatureProvider.SupportType.CHAT;
import static com.android.settings.overlay.SupportFeatureProvider.SupportType.PHONE;

/**
 * Item adapter for support tiles.
 */
public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAdapter.ViewHolder> {

    private static final String STATE_SELECTED_COUNTRY = "STATE_SELECTED_COUNTRY";
    private static final int TYPE_ESCALATION_OPTIONS = R.layout.support_escalation_options;
    private static final int TYPE_ESCALATION_OPTIONS_OFFLINE =
            R.layout.support_offline_escalation_options;
    private static final int TYPE_SUPPORT_TILE = R.layout.support_tile;
    private static final int TYPE_SUPPORT_TILE_SPACER = R.layout.support_tile_spacer;
    private static final int TYPE_SIGN_IN_BUTTON = R.layout.support_sign_in_button;

    private final Activity mActivity;
    private final EscalationClickListener mEscalationClickListener;
    private final SpinnerItemSelectListener mSpinnerItemSelectListener;
    private final SupportFeatureProvider mSupportFeatureProvider;
    private final MetricsFeatureProvider mMetricsFeatureProvider;
    private final View.OnClickListener mItemClickListener;
    private final List<SupportData> mSupportData;

    private String mSelectedCountry;
    private boolean mHasInternet;
    private Account mAccount;

    public SupportItemAdapter(Activity activity, Bundle savedInstanceState,
            SupportFeatureProvider supportFeatureProvider,
            MetricsFeatureProvider metricsFeatureProvider,
            View.OnClickListener itemClickListener) {
        mActivity = activity;
        mSupportFeatureProvider = supportFeatureProvider;
        mMetricsFeatureProvider = metricsFeatureProvider;
        mItemClickListener = itemClickListener;
        mEscalationClickListener = new EscalationClickListener();
        mSpinnerItemSelectListener = new SpinnerItemSelectListener();
        mSupportData = new ArrayList<>();
        // Optimistically assume we have Internet access. It will be updated later to correct value.
        mHasInternet = true;
        if (savedInstanceState != null) {
            mSelectedCountry = savedInstanceState.getString(STATE_SELECTED_COUNTRY);
        } else {
            mSelectedCountry = mSupportFeatureProvider.getCurrentCountryCodeIfHasConfig(PHONE);
        }
        mAccount = mSupportFeatureProvider.getSupportEligibleAccount(mActivity);
        refreshData();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(
                viewType, parent, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        final SupportData data = mSupportData.get(position);
        switch (holder.getItemViewType()) {
            case TYPE_SIGN_IN_BUTTON:
                bindSignInPromoTile(holder, (EscalationData) data);
                break;
            case TYPE_ESCALATION_OPTIONS:
                bindEscalationOptions(holder, (EscalationData) data);
                break;
            case TYPE_ESCALATION_OPTIONS_OFFLINE:
                bindOfflineEscalationOptions(holder, (OfflineEscalationData) data);
                break;
            case TYPE_SUPPORT_TILE_SPACER:
                break;
            default:
                bindSupportTile(holder, data);
                break;
        }
    }

    @Override
    public int getItemViewType(int position) {
        return mSupportData.get(position).type;
    }

    @Override
    public int getItemCount() {
        return mSupportData.size();
    }

    /**
     * Called when a support item is clicked.
     */
    public void onItemClicked(int position) {
        if (position >= 0 && position < mSupportData.size()) {
            final SupportData data = mSupportData.get(position);
            if (data.intent != null &&
                    mActivity.getPackageManager().resolveActivity(data.intent, 0) != null) {
                if (data.metricsEvent >= 0) {
                    mMetricsFeatureProvider.action(mActivity, data.metricsEvent);
                }
                mActivity.startActivityForResult(data.intent, 0);
            }
        }
    }

    public void setHasInternet(boolean hasInternet) {
        if (mHasInternet != hasInternet) {
            mHasInternet = hasInternet;
            refreshEscalationCards();
        }
    }

    public void setAccount(Account account) {
        if (!Objects.equals(mAccount, account)) {
            mAccount = account;
            mSupportFeatureProvider.refreshOperationRules();
            refreshEscalationCards();
        }
    }

    public void onSaveInstanceState(Bundle outState) {
        outState.putString(STATE_SELECTED_COUNTRY, mSelectedCountry);
    }

    /**
     * Create data for the adapter. If there is already data in the adapter, they will be
     * destroyed and recreated.
     */
    private void refreshData() {
        mSupportData.clear();
        addEscalationCards();
        addMoreHelpItems();
        notifyDataSetChanged();
    }

    /**
     * Adds 1 escalation card. Based on current phone state, the escalation card can display
     * different content.
     */
    private void addEscalationCards() {
        if (mAccount == null) {
            addSignInPromo();
        } else if (mHasInternet) {
            addOnlineEscalationCards();
        } else {
            addOfflineEscalationCards();
        }
    }

    /**
     * Finds and refreshes escalation card data.
     */
    private void refreshEscalationCards() {
        if (getItemCount() > 0) {
            final int itemType = getItemViewType(0 /* position */);
            if (itemType == TYPE_SIGN_IN_BUTTON
                    || itemType == TYPE_ESCALATION_OPTIONS
                    || itemType == TYPE_ESCALATION_OPTIONS_OFFLINE) {
                mSupportData.remove(0 /* position */);
                addEscalationCards();
                notifyItemChanged(0 /* position */);
            }
        }
    }

    private void addOnlineEscalationCards() {
        final boolean hasPhoneOperation =
                mSupportFeatureProvider.isSupportTypeEnabled(mActivity, PHONE);
        final boolean hasChatOperation =
                mSupportFeatureProvider.isSupportTypeEnabled(mActivity, CHAT);
        final EscalationData.Builder builder = new EscalationData.Builder(mActivity);
        if (!hasPhoneOperation && !hasChatOperation) {
            // No support at all.
            builder.setTileTitle(R.string.support_escalation_title)
                    .setTileSummary(R.string.support_escalation_unavailable_summary);
        } else if (mSupportFeatureProvider.isAlwaysOperating(PHONE, null /* countryCode */)
                || mSupportFeatureProvider.isAlwaysOperating(CHAT, null /* countryCode */)) {
            // Support is available.
            builder.setTileTitle(R.string.support_escalation_24_7_title)
                    .setTileTitleDescription(R.string.support_escalation_24_7_content_description)
                    .setTileSummary(mActivity.getString(R.string.support_escalation_24_7_summary));
        } else if (mSupportFeatureProvider.isOperatingNow(PHONE)
                || mSupportFeatureProvider.isOperatingNow(CHAT)) {
            // Support is available now.
            builder.setTileTitle(R.string.support_escalation_title)
                    .setTileSummary(R.string.support_escalation_summary);
        } else {
            // Support is now temporarily unavailable.
            builder.setTileTitle(R.string.support_escalation_title)
                    .setTileSummary(
                            mSupportFeatureProvider.getOperationHours(mActivity, PHONE, null,
                                    true /* hasInternet */));
        }
        if (hasPhoneOperation) {
            builder.setText1(R.string.support_escalation_by_phone)
                    .setSummary1(mSupportFeatureProvider.getEstimatedWaitTime(mActivity, PHONE))
                    .setEnabled1(mSupportFeatureProvider.isOperatingNow(PHONE));
        }
        if (hasChatOperation) {
            builder.setText2(R.string.support_escalation_by_chat)
                    .setSummary2(mSupportFeatureProvider.getEstimatedWaitTime(mActivity, CHAT))
                    .setEnabled2(mSupportFeatureProvider.isOperatingNow(CHAT));
        }
        mSupportData.add(0 /* index */, builder.build());
    }

    private void addOfflineEscalationCards() {
        final CharSequence operatingHours;
        final boolean isPhoneSupportAlwaysOperating =
                mSupportFeatureProvider.isAlwaysOperating(PHONE, mSelectedCountry);
        if (isPhoneSupportAlwaysOperating) {
            operatingHours = mActivity.getString(R.string.support_escalation_24_7_summary);
        } else {
            operatingHours = mSupportFeatureProvider.getOperationHours(mActivity,
                    PHONE, mSelectedCountry, false /* hasInternet */);
        }
        mSupportData.add(0 /* index */, new OfflineEscalationData.Builder(mActivity)
                .setCountries(mSupportFeatureProvider.getPhoneSupportCountries())
                .setTollFreePhone(mSupportFeatureProvider.getSupportPhones(
                        mSelectedCountry, true /* isTollFree */))
                .setTolledPhone(mSupportFeatureProvider.getSupportPhones(
                        mSelectedCountry, false /* isTollFree */))
                .setTileTitle(isPhoneSupportAlwaysOperating
                        ? R.string.support_escalation_24_7_title
                        : R.string.support_escalation_title)
                .setTileTitleDescription(isPhoneSupportAlwaysOperating
                        ? R.string.support_escalation_24_7_content_description
                        : R.string.support_escalation_title)
                .setTileSummary(operatingHours)
                .build());
    }

    private void addSignInPromo() {
        mSupportData.add(0 /* index */, new EscalationData.Builder(mActivity, TYPE_SIGN_IN_BUTTON)
                .setText1(R.string.support_sign_in_button_text)
                .setText2(R.string.support_sign_in_required_help)
                .setTileTitle(R.string.support_sign_in_required_title)
                .setTileSummary(R.string.support_sign_in_required_summary)
                .build());
    }

    private void addMoreHelpItems() {
        mSupportData.add(new SupportData.Builder(mActivity, TYPE_SUPPORT_TILE_SPACER).build());
        PackageManager packageManager = mActivity.getPackageManager();
        Intent intent = mSupportFeatureProvider.getHelpIntent(mActivity);
        if (packageManager.resolveActivity(intent, 0) != null) {
            mSupportData.add(new SupportData.Builder(mActivity, TYPE_SUPPORT_TILE)
                    .setIcon(R.drawable.ic_help_24dp)
                    .setTileTitle(R.string.support_help_feedback_title)
                    .setIntent(intent)
                    .setMetricsEvent(MetricsProto.MetricsEvent.ACTION_SUPPORT_HELP_AND_FEEDBACK)
                    .build());
        }
        intent = mSupportFeatureProvider.getTipsAndTricksIntent(mActivity);
        if (packageManager.resolveActivity(intent, 0) != null) {
            mSupportData.add(new SupportData.Builder(mActivity, TYPE_SUPPORT_TILE)
                    .setIcon(R.drawable.ic_lightbulb_outline_24)
                    .setTileTitle(R.string.support_tips_and_tricks_title)
                    .setIntent(intent)
                    .setMetricsEvent(MetricsProto.MetricsEvent.ACTION_SUPPORT_TIPS_AND_TRICKS)
                    .build());
        }
    }

    private void bindEscalationOptions(ViewHolder holder, EscalationData data) {
        holder.tileTitleView.setText(data.tileTitle);
        holder.tileTitleView.setContentDescription(data.tileTitleDescription);
        holder.tileSummaryView.setText(data.tileSummary);
        if (data.text1 == 0) {
            holder.text1View.setVisibility(View.GONE);
        } else {
            holder.text1View.setText(data.text1);
            holder.text1View.setOnClickListener(mEscalationClickListener);
            holder.text1View.setEnabled(data.enabled1 && mHasInternet);
            holder.text1View.setVisibility(View.VISIBLE);
        }
        if (TextUtils.isEmpty(data.text2)) {
            holder.text2View.setVisibility(View.GONE);
        } else {
            holder.text2View.setText(data.text2);
            holder.text2View.setOnClickListener(mEscalationClickListener);
            holder.text2View.setEnabled(data.enabled2 && mHasInternet);
            holder.text2View.setVisibility(View.VISIBLE);
        }
        if (holder.summary1View != null) {
            holder.summary1View.setText(data.summary1);
            holder.summary1View.setVisibility(mHasInternet && !TextUtils.isEmpty(data.summary1)
                    ? View.VISIBLE : View.GONE);
        }
        if (holder.summary2View != null) {
            holder.summary2View.setText(data.summary2);
            holder.summary2View.setVisibility(mHasInternet && !TextUtils.isEmpty(data.summary2)
                    ? View.VISIBLE : View.GONE);
        }
    }

    private void bindOfflineEscalationOptions(ViewHolder holder, OfflineEscalationData data) {
        // Bind Title
        holder.tileTitleView.setText(data.tileTitle);
        holder.tileTitleView.setContentDescription(data.tileTitleDescription);
        holder.tileSummaryView.setText(data.tileSummary);
        // Bind spinner
        final Spinner spinner = (Spinner) holder.itemView.findViewById(R.id.spinner);
        final ArrayAdapter<String> adapter = new ArrayAdapter(
                mActivity, android.R.layout.simple_spinner_dropdown_item, data.countries);
        spinner.setAdapter(adapter);
        final List<String> countryCodes = mSupportFeatureProvider.getPhoneSupportCountryCodes();
        for (int i = 0; i < countryCodes.size(); i++) {
            if (TextUtils.equals(countryCodes.get(i), mSelectedCountry)) {
                spinner.setSelection(i);
                break;
            }
        }
        spinner.setOnItemSelectedListener(mSpinnerItemSelectListener);
        // Bind buttons
        if (data.tollFreePhone != null) {
            holder.text1View.setText(data.tollFreePhone.number);
            holder.text1View.setVisibility(View.VISIBLE);
            holder.text1View.setOnClickListener(mEscalationClickListener);
        } else {
            holder.text1View.setVisibility(View.GONE);
        }
        if (data.tolledPhone != null) {
            holder.text2View.setText(
                    mActivity.getString(R.string.support_international_phone_title));
            holder.text2View.setVisibility(View.VISIBLE);
            holder.text2View.setOnClickListener(mEscalationClickListener);
        } else {
            holder.text2View.setVisibility(View.GONE);
        }

        if (ActivityManager.isUserAMonkey()) {
            holder.text1View.setVisibility(View.GONE);
            holder.text2View.setVisibility(View.GONE);
            spinner.setVisibility(View.GONE);
            holder.itemView.findViewById(R.id.support_text).setVisibility(View.GONE);
        }
    }

    private void bindSignInPromoTile(ViewHolder holder, EscalationData data) {
        holder.tileTitleView.setText(data.tileTitle);
        holder.tileTitleView.setContentDescription(data.tileTitleDescription);
        holder.tileSummaryView.setText(data.tileSummary);
        holder.text1View.setText(data.text1);
        holder.text2View.setText(data.text2);
        holder.text1View.setOnClickListener(mEscalationClickListener);
        holder.text2View.setOnClickListener(mEscalationClickListener);
    }

    private void bindSupportTile(ViewHolder holder, SupportData data) {
        if (holder.iconView != null) {
            holder.iconView.setImageResource(data.icon);
        }
        if (holder.tileTitleView != null) {
            holder.tileTitleView.setText(data.tileTitle);
            holder.tileTitleView.setContentDescription(data.tileTitleDescription);
        }
        if (holder.tileSummaryView != null) {
            holder.tileSummaryView.setText(data.tileSummary);
        }
        holder.itemView.setOnClickListener(mItemClickListener);
    }

    /**
     * Show a disclaimer dialog and start support action after disclaimer has been acknowledged.
     */
    private void tryStartDisclaimerAndSupport(final @SupportFeatureProvider.SupportType int type) {
        if (mSupportFeatureProvider.shouldShowDisclaimerDialog(mActivity)) {
            DialogFragment fragment = SupportDisclaimerDialogFragment.newInstance(mAccount, type);
            fragment.show(mActivity.getFragmentManager(), SupportDisclaimerDialogFragment.TAG);
            return;
        }
        mSupportFeatureProvider.startSupport(mActivity, mAccount, type);
    }

    /**
     * Click handler for starting escalation options.
     */
    private final class EscalationClickListener implements View.OnClickListener {
        @Override
        public void onClick(final View v) {
            if (mAccount == null) {
                switch (v.getId()) {
                    case android.R.id.text1:
                        mMetricsFeatureProvider.action(mActivity,
                                MetricsProto.MetricsEvent.ACTION_SUPPORT_SIGN_IN);
                        mActivity.startActivityForResult(
                                mSupportFeatureProvider.getAccountLoginIntent(),
                                0 /* requestCode */);
                        break;
                    case android.R.id.text2:
                        mActivity.startActivityForResult(
                                mSupportFeatureProvider.getSignInHelpIntent(mActivity),
                                0 /* requestCode */);
                        break;
                }
            } else if (mHasInternet) {
                switch (v.getId()) {
                    case android.R.id.text1:
                        mMetricsFeatureProvider.action(mActivity,
                                MetricsProto.MetricsEvent.ACTION_SUPPORT_PHONE);
                        tryStartDisclaimerAndSupport(PHONE);
                        break;
                    case android.R.id.text2:
                        mMetricsFeatureProvider.action(mActivity,
                                MetricsProto.MetricsEvent.ACTION_SUPPORT_CHAT);
                        tryStartDisclaimerAndSupport(CHAT);
                        break;
                }
            } else {
                switch (v.getId()) {
                    case android.R.id.text1: {
                        final SupportPhone phone = mSupportFeatureProvider
                                .getSupportPhones(mSelectedCountry, true /* isTollFree */);
                        if (phone != null) {
                            final Intent intent = phone.getDialIntent();
                            final boolean canDial = !mActivity.getPackageManager()
                                    .queryIntentActivities(intent, 0)
                                    .isEmpty();
                            if (canDial) {
                                mMetricsFeatureProvider.action(mActivity,
                                        MetricsProto.MetricsEvent.ACTION_SUPPORT_DAIL_TOLLFREE);
                                mActivity.startActivity(intent);
                            }
                        }
                        break;
                    }
                    case android.R.id.text2: {
                        final SupportPhone phone = mSupportFeatureProvider
                                .getSupportPhones(mSelectedCountry, false /* isTollFree */);
                        final SupportPhoneDialogFragment fragment =
                                SupportPhoneDialogFragment.newInstance(phone);
                        mMetricsFeatureProvider.action(mActivity,
                                MetricsProto.MetricsEvent.ACTION_SUPPORT_VIEW_TRAVEL_ABROAD_DIALOG);
                        fragment.show(mActivity.getFragmentManager(),
                                SupportPhoneDialogFragment.TAG);
                        break;
                    }
                }
            }
        }
    }

    private final class SpinnerItemSelectListener implements AdapterView.OnItemSelectedListener {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            final List<String> countryCodes = mSupportFeatureProvider.getPhoneSupportCountryCodes();
            final String selectedCountry = countryCodes.get(position);
            if (!TextUtils.equals(selectedCountry, mSelectedCountry)) {
                mSelectedCountry = selectedCountry;
                refreshEscalationCards();
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            // Do nothing.
        }
    }

    /**
     * {@link RecyclerView.ViewHolder} for support items.
     */
    static final class ViewHolder extends RecyclerView.ViewHolder {

        final ImageView iconView;
        final TextView tileTitleView;
        final TextView tileSummaryView;
        final TextView text1View;
        final TextView text2View;
        final TextView summary1View;
        final TextView summary2View;

        ViewHolder(View itemView) {
            super(itemView);
            iconView = (ImageView) itemView.findViewById(android.R.id.icon);
            tileTitleView = (TextView) itemView.findViewById(R.id.tile_title);
            tileSummaryView = (TextView) itemView.findViewById(R.id.tile_summary);
            text1View = (TextView) itemView.findViewById(android.R.id.text1);
            text2View = (TextView) itemView.findViewById(android.R.id.text2);
            summary1View = (TextView) itemView.findViewById(R.id.summary1);
            summary2View = (TextView) itemView.findViewById(R.id.summary2);
        }
    }

    /**
     * Data for a single support item.
     */
    private static class SupportData {

        final Intent intent;
        final int metricsEvent;
        @LayoutRes
        final int type;
        @DrawableRes
        final int icon;
        @StringRes
        final int tileTitle;
        final CharSequence tileTitleDescription;
        final CharSequence tileSummary;


        private SupportData(Builder builder) {
            this.type = builder.mType;
            this.icon = builder.mIcon;
            this.tileTitle = builder.mTileTitle;
            this.tileTitleDescription = builder.mTileTitleDescription;
            this.tileSummary = builder.mTileSummary;
            this.intent = builder.mIntent;
            this.metricsEvent = builder.mMetricsEvent;
        }

        static class Builder {

            protected final Context mContext;
            @LayoutRes
            private final int mType;
            @DrawableRes
            private int mIcon;
            @StringRes
            private int mTileTitle;
            private CharSequence mTileTitleDescription;
            private CharSequence mTileSummary;
            private Intent mIntent;
            private int mMetricsEvent = -1;

            Builder(Context context, @LayoutRes int type) {
                mContext = context;
                mType = type;
            }

            Builder setIcon(@DrawableRes int icon) {
                mIcon = icon;
                return this;
            }

            Builder setTileTitle(@StringRes int title) {
                mTileTitle = title;
                return this;
            }

            Builder setTileTitleDescription(@StringRes int titleDescription) {
                mTileTitleDescription = mContext.getString(titleDescription);
                return this;
            }

            Builder setTileSummary(@StringRes int summary) {
                mTileSummary = mContext.getString(summary);
                return this;
            }

            Builder setTileSummary(CharSequence summary) {
                mTileSummary = summary;
                return this;
            }

            Builder setMetricsEvent(int metricsEvent) {
                mMetricsEvent = metricsEvent;
                return this;
            }

            Builder setIntent(Intent intent) {
                mIntent = intent;
                return this;
            }

            SupportData build() {
                return new SupportData(this);
            }
        }
    }

    /**
     * Data model for escalation cards.
     */
    private static class EscalationData extends SupportData {

        @StringRes
        final int text1;
        final CharSequence text2;
        final boolean enabled1;
        final boolean enabled2;
        final CharSequence summary1;
        final CharSequence summary2;

        private EscalationData(Builder builder) {
            super(builder);
            this.text1 = builder.mText1;
            this.text2 = builder.mText2;
            this.summary1 = builder.mSummary1;
            this.summary2 = builder.mSummary2;
            this.enabled1 = builder.mEnabled1;
            this.enabled2 = builder.mEnabled2;
        }

        static class Builder extends SupportData.Builder {

            @StringRes
            private int mText1;
            private CharSequence mText2;
            private CharSequence mSummary1;
            private CharSequence mSummary2;
            private boolean mEnabled1;
            private boolean mEnabled2;

            protected Builder(Context context, @LayoutRes int type) {
                super(context, type);
            }

            Builder(Context context) {
                this(context, TYPE_ESCALATION_OPTIONS);
            }

            Builder setEnabled1(boolean enabled) {
                mEnabled1 = enabled;
                return this;
            }

            Builder setText1(@StringRes int text1) {
                mText1 = text1;
                return this;
            }

            Builder setText2(@StringRes int text2) {
                mText2 = mContext.getString(text2);
                return this;
            }

            Builder setText2(CharSequence text2) {
                mText2 = text2;
                return this;
            }

            Builder setSummary1(String summary1) {
                mSummary1 = summary1;
                return this;
            }

            Builder setEnabled2(boolean enabled) {
                mEnabled2 = enabled;
                return this;
            }

            Builder setSummary2(String summary2) {
                mSummary2 = summary2;
                return this;
            }

            EscalationData build() {
                return new EscalationData(this);
            }
        }
    }

    /**
     * Support data for offline mode.
     */
    private static final class OfflineEscalationData extends EscalationData {

        final List<String> countries;
        final SupportPhone tollFreePhone;
        final SupportPhone tolledPhone;

        private OfflineEscalationData(Builder builder) {
            super(builder);
            countries = builder.mCountries;
            tollFreePhone = builder.mTollFreePhone;
            tolledPhone = builder.mTolledPhone;
        }

        static final class Builder extends EscalationData.Builder {

            private List<String> mCountries;
            private SupportPhone mTollFreePhone;
            private SupportPhone mTolledPhone;

            Builder(Context context) {
                super(context, TYPE_ESCALATION_OPTIONS_OFFLINE);
            }

            Builder setCountries(List<String> countries) {
                mCountries = countries;
                return this;
            }

            Builder setTollFreePhone(SupportPhone phone) {
                mTollFreePhone = phone;
                return this;
            }

            Builder setTolledPhone(SupportPhone phone) {
                mTolledPhone = phone;
                return this;
            }

            OfflineEscalationData build() {
                return new OfflineEscalationData(this);
            }
        }
    }
}
