/*
 * 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.app.admin;

import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.TEXT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * The factory reset protection policy determines which accounts can unlock a device that
 * has gone through untrusted factory reset.
 * <p>
 * Only a device owner or profile owner of an organization-owned device can set a factory
 * reset protection policy for the device by calling the {@code DevicePolicyManager} method
 * {@link DevicePolicyManager#setFactoryResetProtectionPolicy(ComponentName,
 * FactoryResetProtectionPolicy)}}.
 * <p>
 * Normally factory reset protection does not kick in if the device is factory reset via Settings.
 * This is also the case when a device owner sets factory reset protection policy. However,
 * when a profile owner of an organization-owned device sets factory reset protection policy that
 * locks the device to specific accounts, the policy will take effect even if factory reset is
 * performed from Settings.
 *
 * @see DevicePolicyManager#setFactoryResetProtectionPolicy
 * @see DevicePolicyManager#getFactoryResetProtectionPolicy
 */
public final class FactoryResetProtectionPolicy implements Parcelable {

    private static final String LOG_TAG = "FactoryResetProtectionPolicy";

    private static final String KEY_FACTORY_RESET_PROTECTION_ACCOUNT =
            "factory_reset_protection_account";
    private static final String KEY_FACTORY_RESET_PROTECTION_ENABLED =
            "factory_reset_protection_enabled";
    private static final String ATTR_VALUE = "value";

    private final List<String> mFactoryResetProtectionAccounts;
    private final boolean mFactoryResetProtectionEnabled;

    private FactoryResetProtectionPolicy(List<String> factoryResetProtectionAccounts,
            boolean factoryResetProtectionEnabled) {
        mFactoryResetProtectionAccounts = factoryResetProtectionAccounts;
        mFactoryResetProtectionEnabled = factoryResetProtectionEnabled;
    }

    /**
     * Get the list of accounts that can provision a device which has been factory reset.
     */
    public @NonNull List<String> getFactoryResetProtectionAccounts() {
        return mFactoryResetProtectionAccounts;
    }

    /**
     * Return whether factory reset protection for the device is enabled or not.
     */
    public boolean isFactoryResetProtectionEnabled() {
        return mFactoryResetProtectionEnabled;
    }

    /**
     * Builder class for {@link FactoryResetProtectionPolicy} objects.
     */
    public static class Builder {
        private List<String> mFactoryResetProtectionAccounts;
        private boolean mFactoryResetProtectionEnabled;

        /**
         * Initialize a new Builder to construct a {@link FactoryResetProtectionPolicy}.
         */
        public Builder() {
            mFactoryResetProtectionEnabled = true;
        };

        /**
         * Sets which accounts can unlock a device that has been factory reset.
         * <p>
         * Once set, the consumer unlock flow will be disabled and only accounts in this list
         * can unlock factory reset protection after untrusted factory reset.
         * <p>
         * It's up to the FRP management agent to interpret the {@code String} as account it
         * supports. Please consult their relevant documentation for details.
         *
         * @param factoryResetProtectionAccounts list of accounts.
         * @return the same Builder instance.
         */
        @NonNull
        public Builder setFactoryResetProtectionAccounts(
                @NonNull List<String> factoryResetProtectionAccounts) {
            mFactoryResetProtectionAccounts = new ArrayList<>(factoryResetProtectionAccounts);
            return this;
        }

        /**
         * Sets whether factory reset protection is enabled or not.
         * <p>
         * Once disabled, factory reset protection will not kick in all together when the device
         * goes through untrusted factory reset. This applies to both the consumer unlock flow and
         * the admin account overrides via {@link #setFactoryResetProtectionAccounts}. By default,
         * factory reset protection is enabled.
         *
         * @param factoryResetProtectionEnabled Whether the policy is enabled or not.
         * @return the same Builder instance.
         */
        @NonNull
        public Builder setFactoryResetProtectionEnabled(boolean factoryResetProtectionEnabled) {
            mFactoryResetProtectionEnabled = factoryResetProtectionEnabled;
            return this;
        }

        /**
         * Combines all of the attributes that have been set on this {@code Builder}
         *
         * @return a new {@link FactoryResetProtectionPolicy} object.
         */
        @NonNull
        public FactoryResetProtectionPolicy build() {
            return new FactoryResetProtectionPolicy(mFactoryResetProtectionAccounts,
                    mFactoryResetProtectionEnabled);
        }
    }

    @Override
    public String toString() {
        return "FactoryResetProtectionPolicy{"
                + "mFactoryResetProtectionAccounts=" + mFactoryResetProtectionAccounts
                + ", mFactoryResetProtectionEnabled=" + mFactoryResetProtectionEnabled
                + '}';
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, @Nullable int flags) {
        int accountsCount = mFactoryResetProtectionAccounts.size();
        dest.writeInt(accountsCount);
        for (String account: mFactoryResetProtectionAccounts) {
            dest.writeString(account);
        }
        dest.writeBoolean(mFactoryResetProtectionEnabled);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final @NonNull Creator<FactoryResetProtectionPolicy> CREATOR =
            new Creator<FactoryResetProtectionPolicy>() {

                @Override
                public FactoryResetProtectionPolicy createFromParcel(Parcel in) {
                    List<String> factoryResetProtectionAccounts = new ArrayList<>();
                    int accountsCount = in.readInt();
                    for (int i = 0; i < accountsCount; i++) {
                        factoryResetProtectionAccounts.add(in.readString());
                    }
                    boolean factoryResetProtectionEnabled = in.readBoolean();

                    return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
                            factoryResetProtectionEnabled);
                }

                @Override
                public FactoryResetProtectionPolicy[] newArray(int size) {
                    return new FactoryResetProtectionPolicy[size];
                }
    };

    /**
     * Restore a previously saved FactoryResetProtectionPolicy from XML.
     * <p>
     * No validation is required on the reconstructed policy since the XML was previously
     * created by the system server from a validated policy.
     * @hide
     */
    @Nullable
    public static FactoryResetProtectionPolicy readFromXml(@NonNull XmlPullParser parser) {
        try {
            boolean factoryResetProtectionEnabled = Boolean.parseBoolean(
                    parser.getAttributeValue(null, KEY_FACTORY_RESET_PROTECTION_ENABLED));

            List<String> factoryResetProtectionAccounts = new ArrayList<>();
            int outerDepth = parser.getDepth();
            int type;
            while ((type = parser.next()) != END_DOCUMENT
                    && (type != END_TAG || parser.getDepth() > outerDepth)) {
                if (type == END_TAG || type == TEXT) {
                    continue;
                }
                if (!parser.getName().equals(KEY_FACTORY_RESET_PROTECTION_ACCOUNT)) {
                    continue;
                }
                factoryResetProtectionAccounts.add(
                        parser.getAttributeValue(null, ATTR_VALUE));
            }

            return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
                    factoryResetProtectionEnabled);
        } catch (XmlPullParserException | IOException e) {
            Log.w(LOG_TAG, "Reading from xml failed", e);
        }
        return null;
    }

    /**
     * @hide
     */
    public void writeToXml(@NonNull XmlSerializer out) throws IOException {
        out.attribute(null, KEY_FACTORY_RESET_PROTECTION_ENABLED,
                Boolean.toString(mFactoryResetProtectionEnabled));
        for (String account : mFactoryResetProtectionAccounts) {
            out.startTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
            out.attribute(null, ATTR_VALUE, account);
            out.endTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
        }
    }

    /**
     * Returns if the policy will result in factory reset protection being locked to
     * admin-specified accounts.
     * <p>
     * When a device has a non-empty factory reset protection policy, trusted factory reset
     * via Settings will no longer remove factory reset protection from the device.
     * @hide
     */
    public boolean isNotEmpty() {
        return !mFactoryResetProtectionAccounts.isEmpty() && mFactoryResetProtectionEnabled;
    }

}
