/*
 * Copyright (C) 2019 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.view.textclassifier;

import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Base64;
import android.util.KeyValueListParser;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;

import java.lang.ref.WeakReference;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * Parses the {@link Settings.Global#TEXT_CLASSIFIER_ACTION_MODEL_PARAMS} flag.
 *
 * @hide
 */
public final class ActionsModelParamsSupplier implements
        Supplier<ActionsModelParamsSupplier.ActionsModelParams> {
    private static final String TAG = TextClassifier.DEFAULT_LOG_TAG;

    @VisibleForTesting
    static final String KEY_REQUIRED_MODEL_VERSION = "required_model_version";
    @VisibleForTesting
    static final String KEY_REQUIRED_LOCALES = "required_locales";
    @VisibleForTesting
    static final String KEY_SERIALIZED_PRECONDITIONS = "serialized_preconditions";

    private final Context mAppContext;
    private final SettingsObserver mSettingsObserver;

    private final Object mLock = new Object();
    private final Runnable mOnChangedListener;
    @Nullable
    @GuardedBy("mLock")
    private ActionsModelParams mActionsModelParams;
    @GuardedBy("mLock")
    private boolean mParsed = true;

    public ActionsModelParamsSupplier(Context context, @Nullable Runnable onChangedListener) {
        final Context appContext = Preconditions.checkNotNull(context).getApplicationContext();
        // Some contexts don't have an app context.
        mAppContext = appContext != null ? appContext : context;
        mOnChangedListener = onChangedListener == null ? () -> {} : onChangedListener;
        mSettingsObserver = new SettingsObserver(mAppContext, () -> {
            synchronized (mLock) {
                Log.v(TAG, "Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS is updated");
                mParsed = true;
                mOnChangedListener.run();
            }
        });
    }

    /**
     * Returns the parsed actions params or {@link ActionsModelParams#INVALID} if the value is
     * invalid.
     */
    @Override
    public ActionsModelParams get() {
        synchronized (mLock) {
            if (mParsed) {
                mActionsModelParams = parse(mAppContext.getContentResolver());
                mParsed = false;
            }
        }
        return mActionsModelParams;
    }

    private ActionsModelParams parse(ContentResolver contentResolver) {
        String settingStr = Settings.Global.getString(contentResolver,
                Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS);
        if (TextUtils.isEmpty(settingStr)) {
            return ActionsModelParams.INVALID;
        }
        try {
            KeyValueListParser keyValueListParser = new KeyValueListParser(',');
            keyValueListParser.setString(settingStr);
            int version = keyValueListParser.getInt(KEY_REQUIRED_MODEL_VERSION, -1);
            if (version == -1) {
                Log.w(TAG, "ActionsModelParams.Parse, invalid model version");
                return ActionsModelParams.INVALID;
            }
            String locales = keyValueListParser.getString(KEY_REQUIRED_LOCALES, null);
            if (locales == null) {
                Log.w(TAG, "ActionsModelParams.Parse, invalid locales");
                return ActionsModelParams.INVALID;
            }
            String serializedPreconditionsStr =
                    keyValueListParser.getString(KEY_SERIALIZED_PRECONDITIONS, null);
            if (serializedPreconditionsStr == null) {
                Log.w(TAG, "ActionsModelParams.Parse, invalid preconditions");
                return ActionsModelParams.INVALID;
            }
            byte[] serializedPreconditions =
                    Base64.decode(serializedPreconditionsStr, Base64.NO_WRAP);
            return new ActionsModelParams(version, locales, serializedPreconditions);
        } catch (Throwable t) {
            Log.e(TAG, "Invalid TEXT_CLASSIFIER_ACTION_MODEL_PARAMS, ignore", t);
        }
        return ActionsModelParams.INVALID;
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            mAppContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
        } finally {
            super.finalize();
        }
    }

    /**
     * Represents the parsed result.
     */
    public static final class ActionsModelParams {

        public static final ActionsModelParams INVALID =
                new ActionsModelParams(-1, "", new byte[0]);

        /**
         * The required model version to apply {@code mSerializedPreconditions}.
         */
        private final int mRequiredModelVersion;

        /**
         * The required model locales to apply {@code mSerializedPreconditions}.
         */
        private final String mRequiredModelLocales;

        /**
         * The serialized params that will be applied to the model file, if all requirements are
         * met. Do not modify.
         */
        private final byte[] mSerializedPreconditions;

        public ActionsModelParams(int requiredModelVersion, String requiredModelLocales,
                byte[] serializedPreconditions) {
            mRequiredModelVersion = requiredModelVersion;
            mRequiredModelLocales = Preconditions.checkNotNull(requiredModelLocales);
            mSerializedPreconditions = Preconditions.checkNotNull(serializedPreconditions);
        }

        /**
         * Returns the serialized preconditions. Returns {@code null} if the the model in use does
         * not meet all the requirements listed in the {@code ActionsModelParams} or the params
         * are invalid.
         */
        @Nullable
        public byte[] getSerializedPreconditions(ModelFileManager.ModelFile modelInUse) {
            if (this == INVALID) {
                return null;
            }
            if (modelInUse.getVersion() != mRequiredModelVersion) {
                Log.w(TAG, String.format(
                        "Not applying mSerializedPreconditions, required version=%d, actual=%d",
                        mRequiredModelVersion, modelInUse.getVersion()));
                return null;
            }
            if (!Objects.equals(modelInUse.getSupportedLocalesStr(), mRequiredModelLocales)) {
                Log.w(TAG, String.format(
                        "Not applying mSerializedPreconditions, required locales=%s, actual=%s",
                        mRequiredModelLocales, modelInUse.getSupportedLocalesStr()));
                return null;
            }
            return mSerializedPreconditions;
        }
    }

    private static final class SettingsObserver extends ContentObserver {

        private final WeakReference<Runnable> mOnChangedListener;

        SettingsObserver(Context appContext, Runnable listener) {
            super(null);
            mOnChangedListener = new WeakReference<>(listener);
            appContext.getContentResolver().registerContentObserver(
                    Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS),
                    false /* notifyForDescendants */,
                    this);
        }

        public void onChange(boolean selfChange) {
            if (mOnChangedListener.get() != null) {
                mOnChangedListener.get().run();
            }
        }
    }
}
