/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ejte.ccl.reporter;

import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;

public class ReporterClient{

    private static SimpleReporterAdapter stat =
            new SimpleReporterAdapter("appserv-tests");

    public static void main(String args[]){
        if(args.length<1){
            usage();
        }
        echo(args[0]+" is the test name");

        String default_desc=args[0]+"_default_description";
        if(args.length>1 && !((args[1].trim()).equals(""))){
            echo(args[1]+" is the test description");
            default_desc = args[1];
        }
        int numTests = 1;
        if (args.length>=3) {
            numTests = Integer.parseInt(args[2]);
        }


        echo("adding description...");
        stat.addDescription(default_desc);
        echo("adding status...");
        if (numTests==1) {
                 stat.addStatus(args[0], stat.DID_NOT_RUN);
        } else {
             for (int i=0;i<numTests; i++) {
                  stat.addStatus(args[0]+"-"+(i+1), stat.DID_NOT_RUN);
             }
        }

        echo("printing summary...");
        stat.printSummary();
    }
    public static void usage(){
       String usg="Usage:"+
           "\tReporterClient <test name> [<test description>]"+
           "\tNote:Test description is not required but recommended";
       echo(usg);
    }
    public static void echo(String msg){
        System.out.println(msg);
    }
}
