package OWL2generator;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 *  The <b><code>WriteOWLHeader</code></b> class processes a user-defined
 *  header file fragment (<code>xlmns</code>-definitions, and prefixes
 *  for the <code>dc</code>, <code>obo</code>, <code>owl</code>,
 *  <code>rdf</code>, <code>xml</code>, <code>xsd</code>, 
 *  <code>foaf</code>, <code>rdfs</code> ontologies), and an OWL
 *  base URI to generate the header section of an OWL/XML ontology.
 *  This class is responsible for creating the initial structure of
 *  the OWL ontology file, including essential namespace bindings,
 *  prefix definitions, and ontology metadata. It relies on a
 *  separate file containing preparatory annotations but contributes
 *  significantly to the overall ontology generation process.
 *  <p>
 *  <b>Key Functionalities:</b>
 *  <p>
 *  Reads Pre-defined Header Data: Reads a text file containing
 *  lines with <code>IRI</code> and <code>LITERAL</code> pairs
 *  to create annotations.
 *  <p>
 *  Processes Header Annotations: Parses each line in the header
 *  file, separating <code>IRI</code> and literal values.
 *  <p>
 *  Generates OWL Annotation Tags: Creates corresponding OWL
 *  <code>&lt;Annotation&gt;</code> tags for each <code>IRI</code>-literal
 *  pair.
 *  <p>
 *  Writes OWL Header: Writes the OWL header section to the output
 *  ontology file, including namespace declarations, prefix definitions,
 *  and the ontology <code>IRI</code>.
 *  <p>
 *  Handles I/O Operations: Manages file reading and writing operations.
 *  <p>
 *  Error Handling: Includes basic error handling for missing required
 *  parameters and file I/O exceptions.
 *  <p>
 *  <b>Additional Notes:</b>
 *  <p>
 *  The class assumes a pre-defined file format for the header data.
 *  <p>
 *  The base URI for the ontology is provided as an argument during object creation. 
 *  <p>
 *  <b>Environment:</b>
 *  <ul>
 *  <li>    IDE:              Eclipse IDE for Java Developers
 *  <li>    Version:          2021-12 (4.22.0)
 *  <li>    Build id:         20211202-1639
 *  <li>    HW Model Name:    iMac, MacOS Monterey, 12.5.1
 *  <li>    Processor Name:   Quad-Core Intel Core i5
 *  <li>    Processor Speed:  3.2 GHz
 *  <li>    Memory:           32 GB 1867 MHz DDR3
 *  <li>    Disk:             APPLE SSD SM0256G    
 *  <li>    Serial:           DGKRC080GG7V
 *  </ul>
 *  @version 1-001
 *  @since   2024/05/23
 *  @author  Edit Hlaszny (https://www.edithlaszny.eu/ edithlaszny@gmail.com)
 */ 

public class WriteOWLHeader 
{
    private String         comment            = "" ;
    private int            countOfAnnotations = 0 ;
    private OWL2_Generator OWL2G              = new OWL2_Generator() ;
	private BufferedReader reader             = null ;
	private BufferedWriter writer             = null ;
	
    WriteOWLHeader(String headerDef,  //  manually pre-made header
                   String dst,        //  result file name 
                   String baseURL,    //  xml:base
                   String comment     //  1st character of line
                  )
    {
    	this.comment = comment ; 
    	
    	try 
        {
          	this.reader = new BufferedReader(new FileReader(headerDef)) ;
            this.writer = new BufferedWriter(new FileWriter(dst)) ;

            writeXMLhdr(baseURL) ;
            
            int    lineNum = 0 ;
      	    String line    = "" ;
      	  
            while ((line = reader.readLine()) != null)
            {
            	lineNum++ ;
            	
        		if  (line.isEmpty() || line.startsWith(this.comment))
            	    continue;

        		if (!line.startsWith("IRI"))
        			fatalErrorMsgAndExit("Missing IRI parameter in " + headerDef +
        					             " / " + lineNum) ;
        		String IRI     = line ;
        		String literal = "" ;
        		
        		if ((literal = reader.readLine()) == null)
        			fatalErrorMsgAndExit("Missing LITERAL parameter in " + headerDef +
                                         " / " + lineNum) ;

        		writeAnnotation(IRI, literal) ;
        		
            }   //  end of while/loop
        } 
        catch (IOException e) 
        {
            e.printStackTrace() ;
        }    	
        finally 
        {
            try 
            {
        	    this.writer.close() ;	            
            } 
            catch (IOException e) 
            {
                System.err.println("Error closing file: " + e.getMessage()) ;
            }
        }
    	
        /**
         *  Logging of the output volume
         */
        OWL2G.log(new StringBuilder()
                      .append("    asserted  " + this.countOfAnnotations + " header annotation(s)\n")
                      .toString()
                 ) ; 
    	
    }   //  end of constructor()
    
    
    private void writeAnnotation(String IRI,
                                 String LITERAL)  throws IOException 
    {
  		String[] parts   = IRI.split("=") ;
  		String   iri     = parts[1] ;

  		         parts   = LITERAL.split("=") ;
  		String   literal = parts[1] ;

    	this.writer.write(new StringBuilder() 
            .append("    <Annotation>\n")
            .append("        <AnnotationProperty abbreviatedIRI=\"" + iri + "\"/>\n")
            .append("        <Literal>" + literal + "</Literal>\n")
            .append("    </Annotation>\n")
            .toString());
    	
    	this.countOfAnnotations++ ;
	
    }   //  end of method writeAnnotation()


    private void writeXMLhdr(String baseURL)   throws IOException 
    {
    	this.writer.write(new StringBuilder() 
            .append("<?xml version=\"1.0\"?>\n")
            .append("<Ontology xmlns=\"http://www.w3.org/2002/07/owl#\"\n")
            .append("    xml:base=\"" + baseURL + "\"\n")
            .append("    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n")
            .append("    xmlns:xml=\"http://www.w3.org/XML/1998/namespace\"\n")
            .append("    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\"\n")
            .append("    xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\n")
            .append("    ontologyIRI=\"" + baseURL + "\">\n")
            .append("    <Prefix name=\"\" IRI=\""  + baseURL +  "\"/>\n")
            .append("    <Prefix name=\"dc\" IRI=\"http://purl.org/dc/elements/1.1/\"/>\n")
            .append("    <Prefix name=\"obo\" IRI=\"http://purl.obolibrary.org/obo/\"/>\n")
            .append("    <Prefix name=\"owl\" IRI=\"http://www.w3.org/2002/07/owl#\"/>\n")
            .append("    <Prefix name=\"rdf\" IRI=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"/>\n")
            .append("    <Prefix name=\"xml\" IRI=\"http://www.w3.org/XML/1998/namespace\"/>\n")
            .append("    <Prefix name=\"xsd\" IRI=\"http://www.w3.org/2001/XMLSchema#\"/>\n")
            .append("    <Prefix name=\"foaf\" IRI=\"http://xmlns.com/foaf/0.1/\"/>\n")
            .append("    <Prefix name=\"rdfs\" IRI=\"http://www.w3.org/2000/01/rdf-schema#\"/>\n")
            .toString());
    	
    }   //  end of method writeXMLhdr()


    private void fatalErrorMsgAndExit(String msg)
    {
		System.err.print(msg) ;
        System.exit(-1);
        
    }   //  end of method fatalErrorMsgAndExit()
    
}   //  end of class WriteOWLHeader
