/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License;
 * you may not use this file except in compliance with the Elastic License.
 */
package org.elasticsearch.protocol.xpack;

import org.elasticsearch.Version;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.license.License;
import org.elasticsearch.tasks.TaskId;

import java.io.IOException;
import java.util.EnumSet;
import java.util.Locale;

/**
 * Fetch information about X-Pack from the cluster.
 */
public class XPackInfoRequest extends ActionRequest {

    public enum Category {
        BUILD, LICENSE, FEATURES;

        public static EnumSet<Category> toSet(String... categories) {
            EnumSet<Category> set = EnumSet.noneOf(Category.class);
            for (String category : categories) {
                switch (category) {
                    case "_all":
                        return EnumSet.allOf(Category.class);
                    case "_none":
                        return EnumSet.noneOf(Category.class);
                    default:
                        set.add(Category.valueOf(category.toUpperCase(Locale.ROOT)));
                }
            }
            return set;
        }
    }

    private boolean verbose;
    private EnumSet<Category> categories = EnumSet.noneOf(Category.class);

    public XPackInfoRequest() {
    }

    public XPackInfoRequest(StreamInput in) throws IOException {
        // NOTE: this does *not* call super, THIS IS A BUG that will be fixed in 8.x
        if (in.getVersion().onOrAfter(Version.V_7_12_0)) {
            // The superclass constructor would set the parent task ID, but for now
            // we must serialize and deserialize manually.
            setParentTask(TaskId.readFromStream(in));
        }
        this.verbose = in.readBoolean();
        EnumSet<Category> categories = EnumSet.noneOf(Category.class);
        int size = in.readVInt();
        for (int i = 0; i < size; i++) {
            categories.add(Category.valueOf(in.readString()));
        }
        this.categories = categories;
        if (hasLicenseVersionField(in.getVersion())) {
            int ignoredLicenseVersion = in.readVInt();
        }
    }

    public void setVerbose(boolean verbose) {
        this.verbose = verbose;
    }

    public boolean isVerbose() {
        return verbose;
    }

    public void setCategories(EnumSet<Category> categories) {
        this.categories = categories;
    }

    public EnumSet<Category> getCategories() {
        return categories;
    }

    @Override
    public ActionRequestValidationException validate() {
        return null;
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        // NOTE: this does *not* call super.writeTo(out), THIS IS A BUG that will be fixed in 8.x
        if (out.getVersion().onOrAfter(Version.V_7_12_0)) {
            getParentTask().writeTo(out);
        }
        out.writeBoolean(verbose);
        out.writeVInt(categories.size());
        for (Category category : categories) {
            out.writeString(category.name());
        }
        if (hasLicenseVersionField(out.getVersion())) {
            out.writeVInt(License.VERSION_CURRENT);
        }
    }

    private static boolean hasLicenseVersionField(Version streamVersion) {
        return streamVersion.onOrAfter(Version.V_7_8_1) && streamVersion.before(Version.V_8_0_0);
    }
}

@@ -581,47 +581,8 @@
 nse;
-%0Aimport org.elasticsearch.tasks.TaskId;
 %0A%0Aim
@@ -1660,350 +1660,18 @@
     
-// NOTE: this does *not* call super, THIS IS A BUG that will be fixed in 8.x%0A        if (in.getVersion().onOrAfter(Version.V_7_12_0)) %7B%0A            // The superclass constructor would set the parent task ID, but for now%0A            // we must serialize and deserialize manually.%0A            setParentTask(TaskId.readFromStream(in));%0A        %7D
+super(in);
 %0A   
@@ -2617,209 +2617,27 @@
     
-// NOTE: this does *not* call super.writeTo(out), THIS IS A BUG that will be fixed in 8.x%0A        if (out.getVersion().onOrAfter(Version.V_7_12_0)) %7B%0A            getParentTask().writeTo(out);%0A        %7D
+super.writeTo(out);
 %0A   

Call superclass constructor in XPackInfoRequest (#67402)