{{>licenseInfo}}

package {{package}};

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.List;

import com.walmartlabs.electrode.reactnative.bridge.Bridgeable;

{{#imports}}
import {{.}};
{{#last}}

{{/last}}
{{/imports}}
import static com.walmartlabs.electrode.reactnative.bridge.util.BridgeArguments.*;

{{#description}}
/**
 * {{description}}
 */
{{/description}}
public class {{requestDataType}} implements Parcelable, Bridgeable {
{{#requestDataType}}
    public static final Creator<{{requestDataType}}> CREATOR =
            new Creator<{{requestDataType}}>() {
                @Override
                public {{requestDataType}} createFromParcel(Parcel in) {
                    return new {{requestDataType}}(in);
                }

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

{{/requestDataType}}
{{#allParams}}
    private {{{dataType}}} {{baseName}};
{{/allParams}}

    private {{requestDataType}}() {
    }

    private {{requestDataType}}(Builder builder) {
{{#allParams}}
        this.{{baseName}} = builder.{{baseName}};
{{/allParams}}
    }

    private {{requestDataType}}(Parcel in) {
        this(in.readBundle());
    }

    public {{requestDataType}}(@NonNull Bundle bundle) {
{{#requiredParams}}
        if (bundle.get("{{baseName}}") == null) {
            throw new IllegalArgumentException("{{baseName}} property is required");
        }
{{/requiredParams}}
{{#allParams}}
{{#isListContainer}}
{{#isItemString}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? getList(bundle.getStringArray("{{baseName}}"), String.class) : null;
{{/isItemString}}
{{#isItemInteger}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? getList(bundle.getIntArray("{{baseName}}"), Integer.class) : null;
{{/isItemInteger}}
{{#isItemBoolean}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? getList(bundle.getBooleanArray("{{baseName}}"), Boolean.class) : null;
{{/isItemBoolean}}
{{#isItemLong}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? getList(bundle.getLongArray("{{baseName}}"), Long.class) : null;
{{/isItemLong}}
{{#isItemDouble}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? getList(bundle.getDoubleArray("{{baseName}}"), Double.class) : null;
{{/isItemDouble}}
{{#isItemFloat}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? getList(bundle.getFloatArray("{{baseName}}"), Float.class) : null;
{{/isItemFloat}}
{{^isPrimitiveType}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? getList(bundle.getParcelableArray("{{baseName}}"), {{baseType}}.class) : null;
{{/isPrimitiveType}}
{{/isListContainer}}
{{^isListContainer}}
{{#isString}}
        this.{{baseName}} = bundle.getString("{{baseName}}");
{{/isString}}
{{#isInteger}}
        this.{{baseName}} = getNumberValue(bundle, "{{baseName}}") == null ? null : getNumberValue(bundle, "{{baseName}}").intValue();
{{/isInteger}}
{{#isLong}}
        this.{{baseName}} = getNumberValue(bundle, "{{baseName}}") == null ? null : getNumberValue(bundle, "{{baseName}}").longValue();
{{/isLong}}
{{#isFloat}}
        this.{{baseName}} = getNumberValue(bundle, "{{baseName}}") == null ? null : getNumberValue(bundle, "{{baseName}}").floatValue();
{{/isFloat}}
{{#isBoolean}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? bundle.getBoolean("{{baseName}}") : null;
{{/isBoolean}}
{{#isObject}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? bundle.getBundle("{{baseName}}") : null;
{{/isObject}}
{{^isPrimitiveType}}
        this.{{baseName}} = bundle.containsKey("{{baseName}}") ? new {{{dataType}}}(bundle.getBundle("{{baseName}}")) : null;
{{/isPrimitiveType}}
{{/isListContainer}}
{{/allParams}}
    }
{{#allParams}}

{{#description}}
    /**
     * {{description}}
     *
     * @return {{{dataType}}}
     */
{{/description}}
{{#required}}
    @NonNull
{{/required}}
{{^required}}
    @Nullable
{{/required}}
    public {{{dataType}}} get{{baseName}}() {
        return {{baseName}};
    }
{{/allParams}}

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeBundle(toBundle());
    }

    @NonNull
    @Override
    public Bundle toBundle() {
        Bundle bundle = new Bundle();
{{#requiredParams}}
{{#isListContainer}}
        updateBundleWithList(this.{{baseName}}, bundle, "{{baseName}}");
{{/isListContainer}}
{{^isListContainer}}
{{#isString}}
        bundle.putString("{{baseName}}", this.{{baseName}});
{{/isString}}
{{#isInteger}}
        bundle.putInt("{{baseName}}", this.{{baseName}});
{{/isInteger}}
{{#isBoolean}}
        bundle.putBoolean("{{baseName}}", this.{{baseName}});
{{/isBoolean}}
{{^isPrimitiveType}}
        bundle.putBundle("{{baseName}}", this.{{baseName}}.toBundle());
{{/isPrimitiveType}}
{{/isListContainer}}
{{/requiredParams}}
{{#optionalParams}}
{{#isListContainer}}
        if ({{baseName}} != null) {
            updateBundleWithList(this.{{baseName}}, bundle, "{{baseName}}");
        }
{{/isListContainer}}
{{^isListContainer}}
{{#isString}}
        if ({{baseName}} != null) {
            bundle.putString("{{baseName}}", this.{{baseName}} );
        }
{{/isString}}
{{#isInteger}}
        if ({{baseName}} != null) {
            bundle.putInt("{{baseName}}", this.{{baseName}});
        }
{{/isInteger}}
{{#isBoolean}}
        if ({{baseName}} != null) {
            bundle.putBoolean("{{baseName}}", this.{{baseName}});
        }
{{/isBoolean}}
{{^isPrimitiveType}}
        if ({{baseName}} != null) {
            bundle.putBundle("{{baseName}}", this.{{baseName}}.toBundle());
        }
{{/isPrimitiveType}}
{{/isListContainer}}
{{/optionalParams}}
        return bundle;
    }

    public static class Builder {
{{#requiredParams}}
        private final {{{dataType}}} {{baseName}};
{{/requiredParams}}
{{#optionalParams}}
        private {{{dataType}}} {{baseName}};
{{/optionalParams}}

        public Builder({{#requiredParams}}@NonNull {{{dataType}}} {{baseName}}{{#hasMore}}, {{/hasMore}}{{/requiredParams}}) {
{{#requiredParams}}
            this.{{baseName}} = {{baseName}};
{{/requiredParams}}
        }

{{#optionalParams}}
        @NonNull
        public Builder {{baseName}}(@Nullable {{{dataType}}} {{baseName}}) {
            this.{{baseName}} = {{baseName}};
            return this;
        }
{{/optionalParams}}

        @NonNull
        public {{requestDataType}} build() {
            return new {{requestDataType}}(this);
        }
    }
}
