/*
 * Copyright (C) 2018 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.accounts;

import android.accounts.Account;
import android.app.ActivityManager;
import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ImageView;

import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.OnLifecycleEvent;

import com.android.settings.R;
import com.android.settings.homepage.SettingsHomepageActivity;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.utils.ThreadUtils;

import java.net.URISyntaxException;
import java.util.List;

/**
 * Avatar related work to the onStart method of registered observable classes
 * in {@link SettingsHomepageActivity}.
 */
public class AvatarViewMixin implements LifecycleObserver {
    private static final String TAG = "AvatarViewMixin";

    @VisibleForTesting
    static final Intent INTENT_GET_ACCOUNT_DATA =
            new Intent("android.content.action.SETTINGS_ACCOUNT_DATA");

    private static final String METHOD_GET_ACCOUNT_AVATAR = "getAccountAvatar";
    private static final String KEY_AVATAR_BITMAP = "account_avatar";
    private static final String KEY_ACCOUNT_NAME = "account_name";
    private static final String EXTRA_ACCOUNT_NAME = "extra.accountName";

    private final Context mContext;
    private final ImageView mAvatarView;
    private final MutableLiveData<Bitmap> mAvatarImage;
    private final ActivityManager mActivityManager;

    @VisibleForTesting
    String mAccountName;

    public AvatarViewMixin(SettingsHomepageActivity activity, ImageView avatarView) {
        mContext = activity.getApplicationContext();
        mActivityManager = mContext.getSystemService(ActivityManager.class);
        mAvatarView = avatarView;
        mAvatarView.setOnClickListener(v -> {
            Intent intent;
            try {
                final String uri = mContext.getResources().getString(
                        R.string.config_account_intent_uri);
                intent = Intent.parseUri(uri, Intent.URI_INTENT_SCHEME);
            } catch (URISyntaxException e) {
                Log.w(TAG, "Error parsing avatar mixin intent, skipping", e);
                return;
            }

            if (!TextUtils.isEmpty(mAccountName)) {
                intent.putExtra(EXTRA_ACCOUNT_NAME, mAccountName);
            }

            final List<ResolveInfo> matchedIntents =
                    mContext.getPackageManager().queryIntentActivities(intent,
                            PackageManager.MATCH_SYSTEM_ONLY);
            if (matchedIntents.isEmpty()) {
                Log.w(TAG, "Cannot find any matching action VIEW_ACCOUNT intent.");
                return;
            }

            final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory.getFactory(
                    mContext).getMetricsFeatureProvider();
            metricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
                    SettingsEnums.CLICK_ACCOUNT_AVATAR, SettingsEnums.SETTINGS_HOMEPAGE,
                    null /* key */, Integer.MIN_VALUE /* value */);

            // Here may have two different UI while start the activity.
            // It will display adding account UI when device has no any account.
            // It will display account information page when intent added the specified account.
            activity.startActivity(intent);
        });

        mAvatarImage = new MutableLiveData<>();
        mAvatarImage.observe(activity, bitmap -> {
            avatarView.setImageBitmap(bitmap);
        });
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart() {
        if (!mContext.getResources().getBoolean(R.bool.config_show_avatar_in_homepage)) {
            Log.d(TAG, "Feature disabled by config. Skipping");
            return;
        }
        if (mActivityManager.isLowRamDevice()) {
            Log.d(TAG, "Feature disabled on low ram device. Skipping");
            return;
        }
        if (hasAccount()) {
            loadAccount();
        } else {
            mAccountName = null;
            mAvatarView.setImageResource(R.drawable.ic_account_circle_24dp);
        }
    }

    @VisibleForTesting
    boolean hasAccount() {
        final Account accounts[] = FeatureFactory.getFactory(
                mContext).getAccountFeatureProvider().getAccounts(mContext);
        return (accounts != null) && (accounts.length > 0);
    }

    private void loadAccount() {
        final String authority = queryProviderAuthority();
        if (TextUtils.isEmpty(authority)) {
            return;
        }

        ThreadUtils.postOnBackgroundThread(() -> {
            final Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                    .authority(authority)
                    .build();
            final Bundle bundle = mContext.getContentResolver().call(uri,
                    METHOD_GET_ACCOUNT_AVATAR, null /* arg */, null /* extras */);
            final Bitmap bitmap = bundle.getParcelable(KEY_AVATAR_BITMAP);
            mAccountName = bundle.getString(KEY_ACCOUNT_NAME, "" /* defaultValue */);
            mAvatarImage.postValue(bitmap);
        });
    }

    @VisibleForTesting
    String queryProviderAuthority() {
        final List<ResolveInfo> providers =
                mContext.getPackageManager().queryIntentContentProviders(INTENT_GET_ACCOUNT_DATA,
                        PackageManager.MATCH_SYSTEM_ONLY);
        if (providers.size() == 1) {
            return providers.get(0).providerInfo.authority;
        } else {
            Log.w(TAG, "The size of the provider is " + providers.size());
            return null;
        }
    }
}
