/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.ode.tools.bpelc.cline;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.ode.tools.ClineCommandContext;
import org.apache.ode.tools.ExecutionException;
import org.apache.ode.tools.bpelc.BpelCompileCommand;
import org.apache.ode.utils.cli.BaseCommandlineTool;
import org.apache.ode.utils.cli.CommandlineFragment;
import org.apache.ode.utils.cli.ConsoleFormatter;
import org.apache.ode.utils.cli.FlagWithArgument;
import org.apache.ode.utils.cli.Fragments;
import org.apache.ode.utils.cli.MultiArgument;

import java.io.File;

public class BpelC extends BaseCommandlineTool {
    private static final Logger __log = LoggerFactory.getLogger(BpelC.class);

    private static FlagWithArgument OUTPUT_DIR = new FlagWithArgument("od","directory",
            "output directory",true);

    private static FlagWithArgument ROOT_WSDL = new FlagWithArgument("wsdl","uri",
            "URI of the WSDL for the process (used with BPEL4WS 1.1 " +
                    "processes, for WS-BPEL 2.0 processes, use <import>).",true);

    private static MultiArgument BPEL_URLS = new MultiArgument("bpelurl",
            "the URLs of BPEL processes to compile.",false);

    private static Fragments DEFAULT = new Fragments(new CommandlineFragment[] {
            LOGGING, ROOT_WSDL, OUTPUT_DIR, BPEL_URLS
    });

    private static final String SYNOPSIS = "compile one or more BPEL processes";

    protected static String getProgramName() {
        return "bpelc";
    }

    public static void main(String[] args) {
        setClazz(BpelC.class);
        if (args.length ==0 || HELP.matches(args)) {
            ConsoleFormatter.printSynopsis(
                    getProgramName(),SYNOPSIS,
                    new Fragments[] {DEFAULT, HELP});
            System.exit(0);
        }
        if (DEFAULT.matches(args)) {
            // Do nothing; we just want the format enforced.
        } else {
            consoleErr("INVALID COMMANDLINE: Try \"" + getProgramName() + " -h\" for help.");
            System.exit(-1);
        }

        // We don't want the normal logging crap; just the coiler messages.
        initLogging();

        BpelCompileCommand bcc = new BpelCompileCommand();

        if (OUTPUT_DIR.isSet()) {
            String outputDir = OUTPUT_DIR.getValue();
            File od = new File(outputDir);
            if (!od.exists() || !od.isDirectory()) {
                consoleErr(outputDir + ": no such directory or not writable.");
                System.exit(-1);
            }
            bcc.setOuputDirectory(od);
        }

        if (ROOT_WSDL.isSet()) {
            bcc.setWsdlImportUri(ROOT_WSDL.getValue());
        }

        String[] b = BPEL_URLS.getValues();
        if (b == null || b.length == 0) {
            consoleErr("At least one process must be specified.");
            System.exit(-1);
        }
        for (String aB : b) bcc.addBpelProcessUrl(aB);
        try {
            bcc.execute(new ClineCommandContext(__log));
        } catch (ExecutionException ee) {
            consoleErr(ee.getMessage());
            System.exit(-1);
        } catch (Throwable t) {
            // This is really quite unexpected, so we should
            // print the stack trace to stderr.
            consoleErr(t.getMessage());
            __log.error(t.getMessage(), t);
            System.exit(-2);
        }
        System.exit(0);
    }
}
