/*===========================================================================
  Copyright (C) 2014 by the Okapi Framework contributors
-----------------------------------------------------------------------------
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
===========================================================================*/

package org.example;

import java.io.File;
import java.util.List;

import net.sf.okapi.lib.xliff2.core.Fragment;
import net.sf.okapi.lib.xliff2.core.Note;
import net.sf.okapi.lib.xliff2.core.Part.GetTarget;
import net.sf.okapi.lib.xliff2.core.Segment;
import net.sf.okapi.lib.xliff2.core.Unit;
import net.sf.okapi.lib.xliff2.document.XLIFFDocument;
import net.sf.okapi.lib.xliff2.reader.Event;
import net.sf.okapi.lib.xliff2.reader.XLIFFReader;
import net.sf.okapi.lib.xliff2.validation.Issue;
import net.sf.okapi.lib.xliff2.validation.Rule;
import net.sf.okapi.lib.xliff2.validation.Validation;
import net.sf.okapi.lib.xliff2.writer.XLIFFWriter;

public class Main {
	
	public static void main (String[] args) {

		// Create a new XLIFF document from scratch
		System.out.println("=== Create a new XLIFF document");
		try ( XLIFFWriter writer = new XLIFFWriter() ) {
			// Create a new document (with English as the source language)
			writer.create(new File("myDocument1.xlf"), "en");
			// Create a unit
			Unit unit = new Unit("u1");
			// Add a segment and get the source content
			Fragment content = unit.appendSegment().getSource();
			content.append("Hello ");
			content.openCodeSpan("1", "<B>");
			content.append("World");
			content.closeCodeSpan("1", "</B>");
			content.append("!");
			// Write the unit
			// Enclosing elements are created with defaults if you don't write
			// them explicitly
			writer.writeUnit(unit);
			// If you forget to write the ends of elements, close() will do it.
			// And if you use a try-with-resources like here it will call close() for you.
		}
		System.out.println("The new document myDocument1.xlf was created.\n");
		
		// Read the document we have created
		System.out.println("=== Read the XLIFF document just created");
		try ( XLIFFReader reader = new XLIFFReader()) {
			reader.open(new File("myDocument1.xlf"));
			// Loop through the reader events
			while (reader.hasNext()) {
				Event event = reader.next();
				// Do something: here print the source content
				if ( event.isUnit() ) {
					Unit unit = event.getUnit();
					for (Segment segment : unit.getSegments()) {
						System.out.println(segment.getSource().getPlainText());
					}
				}
			}
		}
		System.out.println("The document was read.\n");

		File myDocument2 = new File("myDocument2.xlf");
		
		// Now read the document, make a modification (add a note) and re-write it
		System.out.println("=== Read the document, add a note to the units, re-write the result");
		try (
			XLIFFReader reader = new XLIFFReader();
			XLIFFWriter writer = new XLIFFWriter()
		) {
			reader.open(new File("myDocument1.xlf"));
			writer.create(myDocument2, null);
			// Loop through the events
			while (reader.hasNext()) {
				Event event = reader.next();
				// Do whatever modifications you need
				// Here we add a note to any unit we find
				if ( event.isUnit() ) {
					Unit unit = event.getUnit();
					System.out.println(String.format("Adding a note to unit id='%s'", unit.getId()));
					unit.getNotes().add(new Note("My note!"));
				}
				// Then re-write each event
				writer.writeEvent(event);
			}
			// Call writer.close() and reader.close() here
			// if you don't use a try-with-resources like this example.
		}
		System.out.println("The document was read, modified and re-written in myDocument2.xlf.\n");

		// Use the XLIFFDocument class to perform tasks on non-sequential objects 
		System.out.println("=== Read the document into a single object and add a target");
		XLIFFDocument doc = new XLIFFDocument();
		// Load the document
		doc.load(myDocument2);
		// Get the first unit of the first file
		Unit unit = doc.getUnitNode("f1", "u1").get();
		Segment seg = unit.getSegment(0);
		Fragment frag = seg.getTarget(GetTarget.CREATE_EMPTY);
		frag.append("some translation");
		// Also add the target info
		doc.getStartXliffData().setTargetLanguage("fr");
		// Save the document
		doc.save();
		System.out.println("The document was modified and re-written in myDocument2.xlf.\n");
		
		// Make sure we have still a valid document
		XLIFFReader.validate(myDocument2);

		// Use the XLIFFDocument class to perform tasks on non-sequential objects 
		System.out.println("=== Read the document again and use a Validation rule on the unit");
		doc = new XLIFFDocument();
		// Load the document
		doc.load(myDocument2);
		unit = doc.getUnitNode("f1", "u1").get();
		// Create a validation rule and add it
		Validation validation = unit.getValidation();
		validation.add(new Rule("endsWith", ":"));
		validation.prepare();
		// Verify if the rules are respected
		List<Issue> issues = validation.processRules(unit, "f1");
		if ( issues == null ) {
		   System.out.println("No rule found.");
		}
		else if ( issues.isEmpty() ) {
		   System.out.println("No validation rule error found.");
		}
		else {
		   System.out.println("One or more validation errors found:");
		   for ( Issue issue : issues ) {
			   System.out.println("-- "+issue.getText());
		   }
		}
	}

}
