/*
 * Copyright (c) 2005, 2021 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.txw2;

import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JPackage;
import com.sun.codemodel.writer.FileCodeWriter;
import com.sun.codemodel.writer.SingleStreamCodeWriter;
import com.sun.tools.rngom.parse.Parseable;
import com.sun.tools.rngom.parse.compact.CompactParseable;
import com.sun.tools.rngom.parse.xml.SAXParseable;
import com.sun.xml.txw2.annotation.XmlNamespace;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.MessageFormat;
import java.util.Properties;
import java.util.ResourceBundle;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;

/**
 * Controls the various aspects of the TXW generation.
 *
 * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
 */
public class TxwOptions {

    public final JCodeModel codeModel = new JCodeModel();

    /**
     * The package to put the generated code into.
     */
    public JPackage _package;

    /**
     * Always non-null.
     */
    public ErrorListener errorListener;

    /**
     * The generated code will be sent to this.
     */
    CodeWriter codeWriter;

    /**
     * Schema file.
     */
    SchemaBuilder source;

    /**
     * If true, generate attribute/value methods that returns the
     * <code>this</code> object for chaining.
     */
    public boolean chainMethod;

    /**
     * If true, the generated code will not use the package-level
     * {@link XmlNamespace} annotation.
     */
    public boolean noPackageNamespace;

    /**
     * Type of input schema language. One of the {@code Language}
     * constants.
     */
    public Language language;

    /**
     * Type of the schema language.
     */
    public enum Language {
        XML,
        XMLSCHEMA,
        COMPACT
    }

    void parseArguments(String[] args) throws BadCommandLineException {
        String src = null;
        for (int i = 0; i < args.length; i++) {
            if (args[i].length() == 0) {
                throw new BadCommandLineException(getMessage("missingOperand"));
            }
            if (args[i].charAt(0) == '-') {
                int j = parseArgument(args, i);
                if (j == 0) {
                    throw new BadCommandLineException(getMessage("unrecognizedParameter", args[i]));
                }
                i += (j - 1);
            } else {
                src = args[i];
            }
        }
        if (_package == null) {
            _package = codeModel.rootPackage();
        }
        if (codeWriter == null) {
            codeWriter = new SingleStreamCodeWriter(System.out);
        }
        if (src == null) {
            throw new BadCommandLineException(getMessage("missingOperand"));
        }
        try {
            source = makeSourceSchema(src, errorListener);
        } catch (MalformedURLException mue) {
            throw new BadCommandLineException(mue.getMessage(), mue);
        }
    }

    private int parseArgument(String[] args, int i) throws BadCommandLineException {
        if (args[i].equals("-o")) {
            File targetDir = new File(requireArgument("-o", args, ++i));
            try {
                codeWriter = new FileCodeWriter(targetDir);
            } catch (IOException ex) {
                throw new BadCommandLineException(ex.getMessage(), ex);
            }
            return 2;
        }
        if (args[i].equals("-p")) {
            _package = codeModel._package(requireArgument("-p", args, ++i));
            return 2;
        }
        if (args[i].equals("-c")) {
            language = Language.COMPACT;
            return 1;
        }
        if (args[i].equals("-x")) {
            language = Language.XML;
            return 1;
        }
        if (args[i].equals("-xsd")) {
            language = Language.XMLSCHEMA;
            return 1;
        }
        if (args[i].equals("-h")) {
            chainMethod = true;
            return 1;
        }
        return 0;   // unrecognized
    }

    private String requireArgument(String d, String[] args, int i) throws BadCommandLineException {
        if (i == args.length || args[i].startsWith("-")) {
            throw new BadCommandLineException(getMessage("missingOperand"));
        }
        return args[i];
    }

    public void printUsage() {
        System.out.println(getMessage("usage"));
    }

    /**
     * Parses the command line and makes a {@link Parseable} object out of the
     * specified schema file.
     */
    private SchemaBuilder makeSourceSchema(String src, ErrorHandler eh) throws BadCommandLineException, MalformedURLException {
        File f = new File(src);
        final InputSource in = new InputSource(f.toURI().toURL().toExternalForm());

        if (language == null) {
            // auto detect
            if (in.getSystemId().endsWith(".rnc")) {
                language = Language.COMPACT;
            } else if (in.getSystemId().endsWith(".rng")) {
                language = Language.XML;
            } else {
                language = Language.XMLSCHEMA;
            }
        }

        SchemaBuilder sb = null;
        switch (language) {
            case XMLSCHEMA:
                sb = new XmlSchemaLoader(in);
                break;
            case COMPACT:
                sb = new RELAXNGLoader(new CompactParseable(in, eh));
                break;
            case XML:
                sb = new RELAXNGLoader(new SAXParseable(in, eh));
                break;
            default:
                // should not happen
                throw new BadCommandLineException(getMessage("unknownGrammar"));
        }
        return sb;
    }

    /**
     * Gets the version number of TXW.
     *
     * @return TXW version
     */
    public static String getVersion() {
        try {
            Properties p = new Properties();
            p.load(TxwOptions.class.getResourceAsStream("version.properties"));
            return p.get("version").toString();
        } catch (Throwable t) {
            return "unknown";
        }
    }

    private static String getMessage(String key, Object... args) {
        String msg = ResourceBundle.getBundle(TxwOptions.class.getPackage().getName() + ".messages").getString(key);
        return MessageFormat.format(msg, args);
    }
}
