/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.tools.xjc;

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

import com.sun.tools.xjc.generator.bean.field.FieldRendererFactory;
import com.sun.tools.xjc.model.CPluginCustomization;
import com.sun.tools.xjc.model.Model;
import com.sun.tools.xjc.outline.Outline;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;

/**
 * Add-on that works on the generated source code.
 * 
 * <p>
 * This add-on will be called after the default bean generation
 * has finished.
 * 
 * @author
 *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
 *
 * @since
 *      JAXB RI 2.0 EA
 */
public abstract class Plugin {

    /**
     * Default constructor.
     */
    protected Plugin() {
    }

    /**
     * Gets the option name to turn on this add-on.
     *
     * <p>
     * For example, if "abc" is returned, "-abc" will
     * turn on this plugin. A plugin needs to be turned
     * on explicitly, or else no other methods of
     * will be invoked.
     *
     * <p>
     * Starting 2.1, when an option matches the name returned
     * from this method, XJC will then invoke {@link #parseArgument(Options, String[], int)},
     * allowing plugins to handle arguments to this option.
     */
    public abstract String getOptionName();

    /**
     * Gets the description of this add-on. Used to generate
     * a usage screen.
     *
     * @return
     *      localized description message. should be terminated by \n.
     */
    public abstract String getUsage();

    /**
     * Parses an option <code>args[i]</code> and augment
     * the <code>opt</code> object appropriately, then return
     * the number of tokens consumed.
     *
     * <p>
     * The callee doesn't need to recognize the option that the
     * getOptionName method returns.
     *
     * <p>
     * Once a plugin is activated, this method is called
     * for options that XJC didn't recognize. This allows
     * a plugin to define additional options to customize
     * its behavior.
     *
     * <p>
     * Since options can appear in no particular order,
     * XJC allows sub-options of a plugin to show up before
     * the option that activates a plugin (one that's returned
     * by {@link #getOptionName()}.
     *
     * But nevertheless a  needs to be activated
     * to participate in further processing.
     *
     * @return
     *      0 if the argument is not understood.
     *      Otherwise return the number of tokens that are
     *      consumed, including the option itself.
     *      (so if you have an option like "-foo 3", return 2.)
     * @exception BadCommandLineException
     *      If the option was recognized but there's an error.
     *      This halts the argument parsing process and causes
     *      XJC to abort, reporting an error.
     */
    public int parseArgument( Options opt, String[] args, int i ) throws BadCommandLineException, IOException {
        return 0;
    }

    /**
     * Returns the list of namespace URIs that are supported by this plug-in
     * as schema annotations.
     *
     * <p>
     * If a plug-in returns a non-empty list, the JAXB RI will recognize
     * these namespace URIs as vendor extensions
     * (much like "http://java.sun.com/xml/ns/jaxb/xjc"). This allows users
     * to write those annotations inside a schema, or in external binding files,
     * and later plug-ins can access those annotations as DOM nodes.
     *
     * <p>
     * See <a href="http://java.sun.com/webservices/docs/1.5/jaxb/vendorCustomizations.html">
     * http://java.sun.com/webservices/docs/1.5/jaxb/vendorCustomizations.html</a>
     * for the syntax that users need to use to enable extension URIs.
     *
     * @return
     *      can be empty, be never be null.
     */
    public List<String> getCustomizationURIs() {
        return Collections.emptyList();
    }

    /**
     * Checks if the given tag name is a valid tag name for the customization element in this plug-in.
     *
     * <p>
     * This method is invoked by XJC to determine if the user-specified customization element
     * is really a customization or not. This information is used to pick the proper error message.
     *
     * <p>
     * A plug-in is still encouraged to do the validation of the customization element in the
     * {@link #run} method before using any {@link CPluginCustomization}, to make sure that it
     * has proper child elements and attributes.
     *
     * @param nsUri
     *      the namespace URI of the element. Never null.
     * @param localName
     *      the local name of the element. Never null.
     */
    public boolean isCustomizationTagName(String nsUri,String localName) {
        return false;
    }

    /**
     * Notifies a plugin that it's activated.
     *
     * <p>
     * This method is called when a plugin is activated
     * through the command line option (as specified by {@link #getOptionName()}.
     *
     * <p>
     * This is a good opportunity to use
     * {@link Options#setFieldRendererFactory(FieldRendererFactory, Plugin)}
     * if a plugin so desires.
     *
     * <p>
     * Noop by default.
     *
     * @since JAXB 2.0 EA4
     */
    public void onActivated(Options opts) throws BadCommandLineException {
        // noop
    }

    /**
     * Performs the post-processing of the {@link Model}.
     *
     * <p>
     * This method is invoked after XJC has internally finished
     * the model construction. This is a chance for a plugin to
     * affect the way code generation is performed.
     *
     * <p>
     * Compared to the {@link #run(Outline, Options, ErrorHandler)}
     * method, this method allows a plugin to work at the higher level
     * conceptually closer to the abstract JAXB model, as opposed to
     * Java syntax level.
     *
     * <p>
     * Note that this method is invoked only when a
     * is activated.
     *
     * @param model
     *      The object that represents the classes/properties to
     *      be generated.
     *
     * @param errorHandler
     *      Errors should be reported to this handler.
     *
     * @since JAXB 2.0.2
     */
    public void postProcessModel(Model model, ErrorHandler errorHandler) {
        // noop
    }

    /**
     * Run the add-on.
     *
     * <p>
     * This method is invoked after XJC has internally finished
     * the code generation. Plugins can tweak some of the generated
     * code (or add more code) by using {@link Outline} and {@link Options}.
     *
     * <p>
     * Note that this method is invoked only when a
     * is activated.
     * 
     * @param outline
     *      This object allows access to various generated code.
     * 
     * @param errorHandler
     *      Errors should be reported to this handler.
     * 
     * @return
     *      If the add-on executes successfully, return true.
     *      If it detects some errors but those are reported and
     *      recovered gracefully, return false.
     *
     * @throws SAXException
     *      After an error is reported to {@link ErrorHandler}, the
     *      same exception can be thrown to indicate a fatal irrecoverable
     *      error. {@link ErrorHandler} itself may throw it, if it chooses
     *      not to recover from the error.
     */
    public abstract boolean run(
        Outline outline, Options opt, ErrorHandler errorHandler ) throws SAXException ;
}
