/*
 * 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.filediff;

import java.io.*;

public class ModifyReport{
    public static void main(String args[]){
        ModifyReport mf = new ModifyReport();
        if(args.length != 1){
            mf.usage();
            System.exit(0);
        }
        String tobeAdded =
        "<tr> \n"+
        "<td colspan=3 align=center> <font color=RED> <b> Expected Results </b> </font> </td> \n"+
         "</tr>\n"+
        "<tr>\n"+
         "<td> <b><i> Test Location </i></b> </td>\n"+
         "<td> <b><i> Reported Name </i></b> </td>\n"+
         "<td> <b><i> Expected Count[13] </i></b> </td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/ejb/stateless/converter </td> \n"+
         "<td> converter mainID </td> \n"+
         "<td> 1 </td> \n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/ejb/stateless/converter </td> \n"+
         "<td> converter Standalone </td> \n"+
         "<td> 1 </td> \n"+
         "</tr>\n"+
         "<tr> \n"+
         /*"<td>  sqetests/transaction/txglobal </td> \n"+
         "<td> txglobal testTxCommit </td> \n"+
         "<td> 2 </td> \n"+
         "</tr>\n"+
         "<tr> \n"+*/
         "<td>  sqetests/ejb/mdb/simple </td> \n"+
         "<td> simple mdb mainID </td> \n"+
         "<td>  1</td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/ejb/bmp/enroller </td> \n"+
         "<td> enroller bmpID </td> \n"+
         "<td>  1</td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/ejb/cmp/roster </td> \n"+
         "<td> cmp roster:insertInfoID </td> \n"+
         "<td>  3</td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/corba </td> \n"+
         "<td> rmiiiop testID </td> \n"+
         "<td>  1</td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/connector/cci </td> \n"+
         "<td> Connector:cci Connector resource adapter Test status:ID </td> \n"+
         "<td>  1</td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/jndi/url </td> \n"+
         "<td> HTMLReader TestID </td> \n"+
         "<td> 1</td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/web/subclassing </td>\n"+
         "<td> WEBCLIENT </td> \n"+
         "<td> 3</td>\n"+
         "</tr>\n";
/*
         "<tr> \n"+
         "<td>  sqetests/transaction/txglobal </td> \n"+
         "<td> </td> \n"+
         "<td> [Total :1]</td>\n"+
         "</tr>\n"+
         "<tr> \n"+
         "<td>  sqetests/security </td>\n"+
         "<td> </td> \n"+
         "<td> [Total :1]</td>\n"+
         "</tr>\n"+
 */
        mf.modifyFile(args[0], tobeAdded);
    }

    public void modifyFile(String filename, String tobeAdded){
        String fileline = "";
        String fileContent = "";
        StringBuffer filedata = new StringBuffer();  // to read file into, and to insert data into
        String tag = "</TABLE>";
        int breakPoint = -1 ;
        int c;
        try{
            File inputfile = new File(filename);
            BufferedReader in = new BufferedReader(new FileReader(inputfile));
            //System.out.println("Reading original file...");
            while ((fileline = in.readLine()) != null){
                filedata.append(fileline);
            }
            //System.out.println("Finished Reading file. ");
            //System.out.println("Closing input stream...");
            in.close();
            //System.out.println("filedata:\n\n"+filedata);
            // find index of first </TABLE> tag
            // insert new string at the index.
            //System.out.println("breakPoint:"+breakPoint);
            breakPoint=filedata.indexOf(tag);
            if(breakPoint != -1){
                filedata.insert(breakPoint, tobeAdded);
                fileContent = filedata.toString();
                //System.out.println("string inserted");
            } else {
                System.out.println("specified tag: "+tag+" was not found in the report");
            }
            //System.out.println("fileContent:\n\n"+fileContent);
            FileWriter fw = new FileWriter(inputfile);
            fw.write(fileContent);
            fw.close();
            System.out.println("Added Configuration data into report");
        } catch(FileNotFoundException fnfe){
            System.out.println("File is not present. \n"+
                               "Please check the file name and try again");
        } catch(Exception ex){
            ex.printStackTrace();
        }
        //System.out.println("============================================");
    }
    public void usage(){
        System.out.println("Usage:");
        System.out.println("Modify Report <filename>");
    }
}
