/*
 * Copyright (C) 2020 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.content.pm.parsing.component;

import static android.content.pm.parsing.ParsingPackageImpl.sForString;

import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DataClass;
import com.android.internal.util.Parcelling;
import com.android.internal.util.Parcelling.BuiltIn.ForInternedString;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** @hide */
public abstract class ParsedComponent implements Parcelable {

    private static ParsedIntentInfo.ListParceler sForIntentInfos = Parcelling.Cache.getOrCreate(
            ParsedIntentInfo.ListParceler.class);

    @NonNull
    @DataClass.ParcelWith(ForInternedString.class)
    private String name;
    int icon;
    int labelRes;
    @Nullable
    CharSequence nonLocalizedLabel;
    int logo;
    int banner;
    int descriptionRes;

    // TODO(b/135203078): Replace flags with individual booleans, scoped by subclass
    int flags;

    @NonNull
    @DataClass.ParcelWith(ForInternedString.class)
    private String packageName;

    @Nullable
    @DataClass.PluralOf("intent")
    @DataClass.ParcelWith(ParsedIntentInfo.ListParceler.class)
    private List<ParsedIntentInfo> intents;

    private ComponentName componentName;

    @Nullable
    protected Bundle metaData;

    ParsedComponent() {

    }

    @SuppressWarnings("IncompleteCopyConstructor")
    public ParsedComponent(ParsedComponent other) {
        this.metaData = other.metaData;
        this.name = other.name;
        this.icon = other.getIcon();
        this.labelRes = other.getLabelRes();
        this.nonLocalizedLabel = other.getNonLocalizedLabel();
        this.logo = other.getLogo();
        this.banner = other.getBanner();

        this.descriptionRes = other.getDescriptionRes();

        this.flags = other.getFlags();

        this.setPackageName(other.packageName);
        this.intents = new ArrayList<>(other.getIntents());
    }

    public void addIntent(ParsedIntentInfo intent) {
        this.intents = CollectionUtils.add(this.intents, intent);
    }

    @NonNull
    public List<ParsedIntentInfo> getIntents() {
        return intents != null ? intents : Collections.emptyList();
    }

    public ParsedComponent setName(String name) {
        this.name = TextUtils.safeIntern(name);
        return this;
    }

    @CallSuper
    public void setPackageName(@NonNull String packageName) {
        this.packageName = TextUtils.safeIntern(packageName);
        //noinspection ConstantConditions
        this.componentName = null;

        // Note: this method does not edit name (which can point to a class), because this package
        // name change is not changing the package in code, but the identifier used by the system.
    }

    @NonNull
    public ComponentName getComponentName() {
        if (componentName == null) {
            componentName = new ComponentName(getPackageName(), getName());
        }
        return componentName;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        sForString.parcel(this.name, dest, flags);
        dest.writeInt(this.getIcon());
        dest.writeInt(this.getLabelRes());
        dest.writeCharSequence(this.getNonLocalizedLabel());
        dest.writeInt(this.getLogo());
        dest.writeInt(this.getBanner());
        dest.writeInt(this.getDescriptionRes());
        dest.writeInt(this.getFlags());
        sForString.parcel(this.packageName, dest, flags);
        sForIntentInfos.parcel(this.getIntents(), dest, flags);
        dest.writeBundle(this.metaData);
    }

    protected ParsedComponent(Parcel in) {
        // We use the boot classloader for all classes that we load.
        final ClassLoader boot = Object.class.getClassLoader();
        //noinspection ConstantConditions
        this.name = sForString.unparcel(in);
        this.icon = in.readInt();
        this.labelRes = in.readInt();
        this.nonLocalizedLabel = in.readCharSequence();
        this.logo = in.readInt();
        this.banner = in.readInt();
        this.descriptionRes = in.readInt();
        this.flags = in.readInt();
        //noinspection ConstantConditions
        this.packageName = sForString.unparcel(in);
        this.intents = sForIntentInfos.unparcel(in);
        this.metaData = in.readBundle(boot);
    }

    @NonNull
    public String getName() {
        return name;
    }

    public int getIcon() {
        return icon;
    }

    public int getLabelRes() {
        return labelRes;
    }

    @Nullable
    public CharSequence getNonLocalizedLabel() {
        return nonLocalizedLabel;
    }

    public int getLogo() {
        return logo;
    }

    public int getBanner() {
        return banner;
    }

    public int getDescriptionRes() {
        return descriptionRes;
    }

    public int getFlags() {
        return flags;
    }

    @NonNull
    public String getPackageName() {
        return packageName;
    }

    @Nullable
    public Bundle getMetaData() {
        return metaData;
    }
}
