/*
 
Copyright (C) 2008 NTT DATA INTELLILINK CORPORATION
 
This program is free software; you can redistribute it and/or
Modify it under the terms of the GNU General Public License 
as published by the Free Software Foundation, version 2.
 
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied 
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.  See the GNU General Public License for more details.
 
*/

package com.clustercontrol.snmptrap.mibloader.action;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.rmi.AccessException;
import java.rmi.RemoteException;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.ejb.CreateException;
import javax.ejb.DuplicateKeyException;
import javax.naming.NamingException;

import net.percederberg.mibble.MibLoaderException;
import net.percederberg.mibble.MibLoaderLog;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

import com.clustercontrol.dialog.TextAreaDialog;
import com.clustercontrol.snmptrap.ejb.session.MibLoaderController;
import com.clustercontrol.snmptrap.mibloader.util.EjbConnectionManager;
import com.clustercontrol.snmptrap.mibloader.util.Messages;

/**
 * Add MIB Info
 * 
 * @version 2.3.0
 * @since 2.3.0
 */
public class AddMibFile {
	protected ResultSubject subject = null;
	
	/**
	 * Add MIB Info
	 * 
	 * @param filePath
	 * @return true/false
	 */
	public void add(String[] filePaths) {
		subject = new ResultSubject(filePaths);

		Shell shell = 
			PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
		ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
		try {
			dialog.run(true, true, new IRunnableWithProgress() {
				public void run(IProgressMonitor monitor) 
				throws InvocationTargetException, InterruptedException {
					
					monitor.beginTask(
							Messages.getString("message.snmptrap.trap.12"), 
							subject.getFilePathSize() * 2);
					
					addMib(monitor);
					
					monitor.done();
				}
			} );
		} catch(InvocationTargetException e) {
			e.printStackTrace();
		} catch(InterruptedException e) {
			subject.cancel();
		}

		openResult(shell);
	}
	
	/**
	 * Add MIB Info
	 * 
	 * @param monitor
	 * @throws InterruptedException
	 */
	protected void addMib(IProgressMonitor monitor) throws InterruptedException {
		MibLoaderController mibLoader = 
			EjbConnectionManager.getConnectionManager().getMibLoaderController();
		
		try {
			mibLoader.CheckPermission();
		} catch (RemoteException e1) {
			if(e1 instanceof AccessException)
				subject.accessError();
			else
				subject.connectError();
			return;
		}

		EntityFactory factory = new EntityFactory();
		
		for(int i = 0; i < subject.getFilePathSize(); i++){
			monitor.subTask(subject.getFilePath(i));
			
			if(monitor.isCanceled())
				throw new InterruptedException();
			
			boolean createResult = false;
			try {
				factory.create(subject.getFilePath(i));
				createResult = true;
			} catch (IOException e) {
				subject.ioError(i);
			} catch (MibLoaderException e) {
				outputLog(subject.getFilePath(i), e.getLog());
				subject.noDependent(i);
			}
			
			monitor.worked(1);
			
			if(monitor.isCanceled())
				throw new InterruptedException();
			
			try {
				if(createResult){
					if(factory.getTrapsData().size() > 0){
						mibLoader.AddMib(factory.getMibData(), factory.getTrapsData());
						subject.success(i);
					}
					else
						subject.noTrap(i);
				}
			} catch (RemoteException e) {
				subject.error(i);
			} catch (CreateException e) {
				if(e instanceof DuplicateKeyException)
					subject.duplicate(i);
				else
					subject.error(i);
			} catch (NamingException e) {
				subject.error(i);
			}
			
			monitor.worked(1);
		}
	}
	
	/**
	 * show result
	 * 
	 * @param shell
	 */
	protected void openResult(Shell shell) {
		TextAreaDialog txtDialog = 
			new TextAreaDialog(shell, Messages.getString("end"), false);
		
		StringBuilder message = new StringBuilder();
		
		if(subject.isConnectError()){
			message.append(Messages.getString("message.snmptrap.trap.13") + "\n\n");
		}
		else if(subject.isAccessError()){
			message.append(Messages.getString("message.accesscontrol.16") + "\n\n");
		}
		else if(subject.isCancel()){
			message.append(Messages.getString("message.snmptrap.trap.10") + "\n\n");
		}
		
		int success = subject.getSuccessCount();
		int warning = subject.getDuplicateCount() + subject.getNoDependentCount() + subject.getNoTrapCount();
		int failed = subject.getErrorCount() + subject.getIoErrorCount();
		
		message.append(Messages.getString("successful") + " : " + success + "\n");
		message.append(Messages.getString("failed") + " : " + failed + "\n");
		message.append(Messages.getString("warning") + " : " + warning + "\n\n");
		
		if(success > 0){
			message.append("-------------- " + Messages.getString("successful") + " ----------------------------\n\n");
			
			message.append(getFileListMessages(
					Messages.getString("message.snmptrap.trap.9"), 
					subject.getSuccessList()));
		}
		
		if(failed > 0){
			message.append("-------------- " + Messages.getString("failed") + " ----------------------------\n\n");
			
			message.append(getFileListMessages(
					Messages.getString("message.snmptrap.trap.5"), 
					subject.getIoErrorList()));
			
			message.append(getFileListMessages(
					Messages.getString("message.snmptrap.trap.7"), 
					subject.getErrorList()));
		}
		
		if(warning > 0){
			message.append("-------------- " + Messages.getString("warning") + " ----------------------------\n\n");
			
			message.append(getFileListMessages(
					Messages.getString("message.snmptrap.trap.8"), 
					subject.getDuplicateList()));
			
			message.append(getFileListMessages(
					Messages.getString("message.snmptrap.trap.11"), 
					subject.getNoTrapList()));
			
			message.append(getFileListMessages(
					Messages.getString("message.snmptrap.trap.6"), 
					subject.getNoDependentList()));
		}
		
		txtDialog.setText(message.toString());
		txtDialog.open();
	}
	
	/**
	 * get file list
	 * 
	 * @param header
	 * @param list
	 * @return
	 */
	protected String getFileListMessages(String header, List<String> list) {
		
		if(list.size() > 0){
			StringBuilder message = new StringBuilder();
			
			message.append(" " + header + "\n");
			for(String file : list){
				message.append(" " + file + "\n");
			}
			message.append("\n");
			
			return message.toString();
		}
		else{
			return "";
		}
	}
	
	/**
	 * output log file
	 * output error message
	 * 
	 * @param file
	 * @param log
	 */
	protected void outputLog(String file, MibLoaderLog log) {
		Format format = new SimpleDateFormat("yyyyMMddHHmmss");
		String fileName = file + "_" + format.format(new Date()) + ".log";
		try {
			PrintWriter writer = new PrintWriter(fileName);
			log.printTo(writer);
		} catch (FileNotFoundException e) {
		}
	}
}