package com.javahonk;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import com.javahonk.bean.Powertrain;
import com.javahonk.bean.Vehicle;
import com.javahonk.bean.Vehicles;
import com.javahonk.bean.Wheel;
import com.javahonk.bean.Wheels;

public class ParseXMLGenerateReport {

	public static String generateReportFromXMLToFileAndConsole(
			String xmlFilePath, String reportFilePath) {

		BufferedWriter bw = null;
		String fileProcessMessage = "\n\nFile processed successfully";
		try {

			if (null == xmlFilePath && null == reportFilePath)
				return "XML and Report file is null";
			if (null == xmlFilePath)
				return "XML file is null";
			if (null == reportFilePath)
				return "Report file is null";
			if (null != xmlFilePath && null != reportFilePath
					&& xmlFilePath.trim().equalsIgnoreCase("")
					&& reportFilePath.trim().equalsIgnoreCase(""))
				return "XML and Report file is empty";
			if (null != xmlFilePath && xmlFilePath.trim()
					.equalsIgnoreCase(""))
				return "XML file is empty";
			if (null != reportFilePath
					&& reportFilePath.trim().equalsIgnoreCase(""))
				return "Report file is empty";
			File writeReportToFile = new File(reportFilePath);
			if (!writeReportToFile.exists()) {
				writeReportToFile.createNewFile();
			}

			FileWriter fw = new FileWriter(writeReportToFile
					.getAbsoluteFile());
			bw = new BufferedWriter(fw);

			File file = new File(xmlFilePath);
			JAXBContext jaxbContext = JAXBContext
					.newInstance(Vehicles.class);

			Unmarshaller jaxbUnmarshaller = jaxbContext
					.createUnmarshaller();
			Vehicles vehicles = (Vehicles) jaxbUnmarshaller
					.unmarshal(file);
			List<Vehicle> vehicles1 = vehicles.getVehiclesList();
			int bigWheel = 0;
			int bicycle = 0;
			int motorcycle = 0;
			int hangGlider = 0;
			int car = 0;

			System.out.println("Each vehicle id and its "
					+ "type report\n");
			bw.write("Each vehicle id and its type report\n\n");

			if (null != vehicles1) {
				for (Vehicle vehicle : vehicles1) {

					String id = vehicle.getId();
					String frameMaterial = vehicle.getFrame()
							.getMaterial();
					String powertrainValue = null;
					String wheelMaterial = null;
					int noOfWheel = 0;
					List<Powertrain> powertrainsList = vehicle
							.getPowertrainsList();
					for (Powertrain powertrain : powertrainsList) {
						powertrainValue = powertrain.getHuman();
					}

					List<Wheels> wheels = vehicle.getWheelsList();

					if (null != wheels) {
						for (Wheels wheels2 : wheels) {
							noOfWheel = wheels2.getWheelsList().size();
							List<Wheel> wheels3 = wheels2.getWheelsList();
							for (Wheel wheel : wheels3) {
								wheelMaterial = wheel.getMaterial();
							}
						}
					}

					if (frameMaterial.equalsIgnoreCase("plastic")
							&& powertrainValue.equalsIgnoreCase("Human")
							&& wheelMaterial.equalsIgnoreCase("Plastic")
							&& noOfWheel == 3) {
						bigWheel++;
						System.out.println("Vehicle Id: " + id
								+ "  Vehicle Type: Big Wheel");
						bw.write("Vehicle Id: " + id
								+ "  Vehicle Type: Big Wheel\n");

					}

					if (frameMaterial.equalsIgnoreCase("metal")
							&& powertrainValue
							.equalsIgnoreCase("Human")
							&& wheelMaterial
							.equalsIgnoreCase("Plastic")
							&& noOfWheel == 2) {
						bicycle++;
						System.out.println("Vehicle Id: " + id
								+ "  Vehicle Type: Bicycle");
						bw.write("Vehicle Id: " + id
								+ "  Vehicle Type: Bicycle\n");

					}

					if (frameMaterial.equalsIgnoreCase("metal")
							&& powertrainValue
									.equalsIgnoreCase(""
											+ "Internal Combustion")
							&& wheelMaterial.equalsIgnoreCase("metal")
							&& noOfWheel == 2) {
						motorcycle++;
						System.out.println("Vehicle Id: " + id
								+ "  Vehicle Type: Motorcycle");
						bw.write("Vehicle Id: " + id
								+ "  Vehicle Type: Motorcycle\n");

					}

					if (frameMaterial.equalsIgnoreCase("plastic")
							&& powertrainValue
							.equalsIgnoreCase("Bernoulli")
							&& noOfWheel == 0) {
						hangGlider++;
						System.out.println("Vehicle Id: " + id
								+ "  Vehicle Type: Hang Glider");
						bw.write("Vehicle Id: " + id
								+ "  Vehicle Type: Hang Glider\n");

					}

					if (frameMaterial.equalsIgnoreCase("metal")
							&& powertrainValue
									.equalsIgnoreCase("Internal Combustion")
							&& wheelMaterial.equalsIgnoreCase("metal")
							&& noOfWheel == 4) {
						car++;
						System.out.println("Vehicle Id: " + id
								+ "  Vehicle Type: Car");
						bw.write("Vehicle Id: " + id 
								+ "  Vehicle Type: Car\n");

					}

				}
			} else {
				bw.write("No matching vehicle found");
				fileProcessMessage = "No matching vehicle found";
				return fileProcessMessage;
			}
			if (bigWheel == 0 && bicycle == 0 && motorcycle == 0
					&& hangGlider == 0 && car == 0) {
				bw.write("No matching vehicle found");
				fileProcessMessage = "No matching vehicle found";
				return fileProcessMessage;
			} else {
				System.out.println("\nType of vehicle summary\n");
				System.out.println("Total no of vehicle: "
						+ (bigWheel + bicycle + motorcycle 
								+ hangGlider + car)
						+ "\n");
				System.out.println("Big Wheel: " + bigWheel);
				System.out.println("Bicycle: " + bicycle);
				System.out.println("Motorcycle: " + motorcycle);
				System.out.println("Hang Glider: " + hangGlider);
				System.out.println("Car: " + car);

				bw.write("\nType of vehicle summary\n\n");
				bw.write("Total no of vehicle: "
						+ (bigWheel + bicycle + motorcycle 
								+ hangGlider + car)
						+ "\n\n");
				bw.write("Big Wheel: " + bigWheel + "\n");
				bw.write("Bicycle: " + bicycle + "\n");
				bw.write("Motorcycle: " + motorcycle + "\n");
				bw.write("Hang Glider: " + hangGlider + "\n");
				bw.write("Car: " + car + "\n");
			}

		} catch (JAXBException e) {
			fileProcessMessage = e.getCause().toString();
			return fileProcessMessage;
		} catch (IOException e) {
			fileProcessMessage = e.getCause().toString();

		} finally {
			try {
				if (null != bw)
					bw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return fileProcessMessage;

	}

}
