/*
 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     bstefanescu
 */
package org.nuxeo.ecm.automation;

import java.io.Serializable;
import java.util.Arrays;

import org.nuxeo.common.xmap.annotation.XNode;
import org.nuxeo.common.xmap.annotation.XNodeList;
import org.nuxeo.common.xmap.annotation.XObject;
import org.nuxeo.ecm.automation.core.Constants;
import org.nuxeo.ecm.automation.core.OperationChainContribution;

/**
 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
 */
public class OperationDocumentation implements
        Comparable<OperationDocumentation>, Serializable {

    private static final long serialVersionUID = 1L;

    public String id;

    /**
     * an array of size multiple of 2. Each pair in the array is the input and
     * output type of a method.
     */
    public String[] signature;

    public String category;

    public String label;

    public String requires;

    public String since;

    /**
     * @since 5.9.1
     */
    public String deprecatedSince;

    /**
     * @since 5.9.1
     */
    public boolean addToStudio;

    /**
     * @since 5.9.1
     */
    public String implementationClass;

    public String description;

    public Param[] params;

    /**
     * The operations listing in case of a chain.
     */
    public OperationChainContribution.Operation[] operations;

    // optional URL indicating the relative path (relative to the automation
    // service home)
    // of the page where the operation is exposed
    public String url;

    public OperationDocumentation(String id) {
        this.id = id;
        this.url = id;
    }

    @XObject("param")
    public static class Param implements Serializable, Comparable<Param> {
        private static final long serialVersionUID = 1L;

        @XNode("@name")
        public String name;

        @XNode("@description")
        public String description;

        @XNode("@type")
        public String type; // the data type

        public String widget; // the widget type

        @XNodeList(value = "values", type = String[].class, componentType = String.class)
        public String[] values; // the default values

        @XNode("@order")
        public int order;

        @XNode("@required")
        public boolean isRequired;

        public Param() {
        }

        public String getName() {
            return name;
        }

        /**
         * @since 5.7.3
         */
        public String getDescription() {
            return description;
        }

        public String getType() {
            return type;
        }

        public String getWidget() {
            return widget;
        }

        public String[] getValues() {
            return values;
        }

        public boolean isRequired() {
            return isRequired;
        }

        public int getOrder() {
            return order;
        }

        @Override
        public String toString() {
            return name + " [" + type + "] "
                    + (isRequired ? "required" : "optional");
        }

        public int compareTo(Param o) {
            if (order != 0 && o.order != 0) {
                if (order < o.order) {
                    return -1;
                } else if (order > o.order) {
                    return 1;
                }
            }
            if (isRequired && !o.isRequired) {
                return -1;
            }
            if (o.isRequired && !isRequired) {
                return 1;
            }
            return name.compareTo(o.name);
        }
    }

    public int compareTo(OperationDocumentation o) {
        String s1 = label == null ? id : label;
        String s2 = o.label == null ? o.id : o.label;
        return s1.compareTo(s2);
    }

    public String getDescription() {
        return description;
    }

    /**
     * @since 5.9.1
     */
    public String getSince() {
        return since;
    }

    /**
     * @since 5.9.1
     */
    public String getDeprecatedSince() {
        return deprecatedSince;
    }

    /**
     * @since 5.9.1
     */
    public boolean isAddToStudio() {
        return addToStudio;
    }

    /**
     * @since 5.9.1
     */
    public String getImplementationClass() {
        return implementationClass;
    }

    /**
     * @since 5.9.4
     */
    public boolean isChain() {
        return (id != null && id.startsWith(Constants.CHAIN_ID_PREFIX))
                || Constants.CAT_CHAIN.equals(category);
    }

    public String[] getSignature() {
        return signature;
    }

    public String getCategory() {
        return category;
    }

    public String getId() {
        return id;
    }

    public String getUrl() {
        return url;
    }

    public String getLabel() {
        return label;
    }

    public String getRequires() {
        return requires;
    }

    public Param[] getParams() {
        return params;
    }

    public OperationChainContribution.Operation[] getOperations() {
        return operations;
    }

    @Override
    public String toString() {
        return category + " > " + label + " [" + id + ": "
                + Arrays.asList(signature) + "] (" + params + ")\n"
                + description;
    }
}

@@ -2249,24 +2249,54 @@
  data type%0A%0A
+        // is this useful (?)%0A
         publ
@@ -2329,24 +2329,54 @@
 idget type%0A%0A
+        // is this useful (?)%0A
         @XNo
@@ -2396,17 +2396,16 @@
 = %22value
-s
 %22, type 
@@ -2507,16 +2507,46 @@
 values%0A%0A
+        // is this useful (?)%0A
         
@@ -2589,16 +2589,46 @@
 order;%0A%0A
+        // is this useful (?)%0A
         

fix default values for param (use 'value' tag instead of 'values' as it's a multiple tag) + add comments