/*
 * 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>");
    }
}
