package OWLpreprocessing;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class OWL_DataPropertyEvaluator 
{
    private final int DATA_PROPERTY_NAME = 0;
    private final int DATA_PROPERTY_TYPE = 1;
    private final int DATA_PROPERTY_ANNOTATION = 2;

    /**
     * Common file handling methods
     */
    private OWL_BufferedWriterUtils bwu = new OWL_BufferedWriterUtils() ;
    private String                  DBname = null ;
    
    // Pattern to match: name, whitespace, type, whitespace, "annotation"
    private static final Pattern LINE_PATTERN = Pattern.compile("^(\\S+)\\s+(\\S+)\\s+\"(.*)\"\\s*$");

    OWL_DataPropertyEvaluator() { ; }
    
    OWL_DataPropertyEvaluator(String DBname,
                              String inputFile,
                              String outputFile
                             )
    {
    	this.DBname = DBname ;
    	
    	writeSQLfileHdr(outputFile) ;

    	int data_property_ID = 1 ;
    	
    	String SQLcontent = "" ;
        ArrayList<String[]> rows = new OWL_DataPropertyEvaluator().evalDataPropertyDefs(inputFile);
    	for (String[] row : rows) 
        {
    		SQLcontent = 
            "INSERT INTO DATA_PROPERTIES (data_property_ID, "
                                       + "data_property_IRI, "
    		                           + "data_property_type, "
            		                   + "data_property_annotationtype, "
    		                           + "super_data_property_IRI)\n" +
    		"    VALUES ('" + data_property_ID              + "',  '"  
                  	        + row[DATA_PROPERTY_NAME]       + "', '" 
	                        + row[DATA_PROPERTY_TYPE]       + "', '" 
    		                + row[DATA_PROPERTY_ANNOTATION] + "', "
    		                + "'owl:topDataProperty') ; \n" ;

    		addSQLcontent(outputFile, SQLcontent, true) ;
    		
    		data_property_ID++ ; // could not be defined as autoincremented field
    		
    	}   //  end of for-loop
    	
    	addSQLcontentAndClose(outputFile, 
    			              "\nCOMMIT ; \n\n--   end of " + outputFile + "\n", 
    			              true
    			             ) ;
    	
    }   //  end of 2nd constructor

	private void addSQLcontent(String SQLfile, String content, boolean appendMode)
	{
        try  
        {
        	FileWriter fw = new FileWriter(new File(SQLfile), appendMode) ;

            fw.write(content) ;
            fw.flush() ;
        }
        catch (IOException e) { e.printStackTrace() ; }
		
	}   //  end of method addSQLcontent()

	private void addSQLcontentAndClose(String SQLfile, String content, boolean appendMode)
	{
        try  
        {
        	FileWriter fw = new FileWriter(new File(SQLfile), appendMode) ;

            fw.write(content) ;
            fw.flush();
            fw.close() ;
        }
        catch (IOException e) { e.printStackTrace() ; }
		
	}   //  end of method addSQLcontentAndClose()
	
    private ArrayList<String[]> evalDataPropertyDefs(String inFileName) //throws IOException 
    {
        ArrayList<String[]> results = new ArrayList<>();

        Path path = Path.of(inFileName);
        try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) 
        {
            String line;
            while ((line = reader.readLine()) != null) 
            {
                String trimmed = line.trim();
 
                if (trimmed.isEmpty()) 
                {
                    continue;
                }
                
                if (trimmed.startsWith("#")) {
                    continue;
                }

                Matcher matcher = LINE_PATTERN.matcher(trimmed);
                if (!matcher.matches()) 
                {
                    // Skip lines that don't conform to the expected structure
                    continue;
                }

                String[] entry = new String[3];
                entry[DATA_PROPERTY_NAME] = matcher.group(1);
                entry[DATA_PROPERTY_TYPE] = matcher.group(2);
                entry[DATA_PROPERTY_ANNOTATION] = matcher.group(3);
                results.add(entry);
            }
        }
        catch (IOException e) { e.printStackTrace() ; }

        return results;
        
    }   //  end of method evalDataPropertyDefs()

    private void writeSQLfileHdr(String outFile)
    {
    	String  description = "The SQL file contains ~50 data properties\n" +
                              "                 with their IRIs, types, and annoations" ;
    	String  content = 
    			"/*\n" +          
                "    Title:       " + outFile + "\n" +         
                "    Description: " + description + "\n" +         
                "    Format:      OWL/XML encoding" + "\n" +         
                "    Written by:  Java class " + this.getClass().getSimpleName() + "\n" +         
                "    Date:        " + bwu.getCurrTime() + "\n" +         
                " */ \n" +          
                "USE   " + this.DBname + " ; \n" +         
                "\n" +          
                "SET   TRANSACTION READ WRITE ; \n" +         
                "START TRANSACTION ; \n" ;         

    	//                              appendMode
    	addSQLcontent(outFile, content, false) ;
    	
    }   //  end of method writeSQLfileHdr()
	
}   //  end of class OWL_DataPropertyEvaluator
