/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.wsdl.validation.internal.ui.eclipse;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.wsdl.validation.internal.IValidationMessage;
import org.eclipse.wst.wsdl.validation.internal.IValidationReport;
import org.eclipse.wst.wsdl.validation.internal.ValidationMessageImpl;
import org.eclipse.wst.wsdl.validation.internal.xml.XMLMessageInfoHelper;
import org.eclipse.wst.xml.ui.internal.validation.core.ValidateAction;

/**
 * Eclipse action for running the WSDL validator. 
 */
public class ValidateWSDLAction extends ValidateAction
{
  private static final String REFERENCED_FILE_ERROR_OPEN = "referencedFileError(";

  private static final String REFERENCED_FILE_ERROR_CLOSE = ")";
  private final String FILE_PROTOCOL = "file:///";

  private static final String _UI_SAVE_DIRTY_FILE_MESSAGE = "_UI_SAVE_DIRTY_FILE_MESSAGE";

  private static final String _UI_SAVE_DIRTY_FILE_TITLE = "_UI_SAVE_DIRTY_FILE_TITLE";
  private static final String _UI_REF_FILE_ERROR_MESSAGE = "_UI_REF_FILE_ERROR_MESSAGE";
  private static final String NESTED_ERRORS = "NESTED_ERRORS";

  private InputStream inputStream = null;
  /**
   * Constructor.
   * 
   * @param file The file to validate.
   * @param showDialog Whether to show a dialog with the status upon completion.
   */
  public ValidateWSDLAction(IFile file, boolean showDialog)
  {
  	super(file, showDialog);
  }


  /**
   * Validate the given file and assign markers correspondingly to the file. If
   * required, show a dialog with the results of the validation.
   * 
   * @param file The file to validate.
   */
  protected void validate(final IFile file)
  {
    final ValidationOutcome validationOutcome = new ValidationOutcome();
    IWorkspaceRunnable op = new IWorkspaceRunnable()
    {
      public void run(IProgressMonitor progressMonitor) throws CoreException
      {
        WSDLValidator wsdlValidator = WSDLValidator.getInstance();
        clearMarkers(file);
        IValidationReport valReport = null;

        String location = null;
        try
        {
          location = file.getLocation().toFile().getCanonicalFile().getAbsolutePath();
        }
        catch (IOException e)
        {
          location = file.getLocation().toString();
        }
        location = location.replace('\\','/');
        if (location.startsWith("/"))
        {
          valReport = wsdlValidator.validate(FILE_PROTOCOL + location.substring(1), inputStream);
        }
        else
        {
          valReport = wsdlValidator.validate(FILE_PROTOCOL + location, inputStream);
        }
        validationOutcome.isWSDLValid = valReport.isWSDLValid();
        validationOutcome.isValid = !valReport.hasErrors();
        if (valReport.getValidationMessages().length == 0)
        {
          validationOutcome.hasMessages = false;
        }
        else
        {
          validationOutcome.hasMessages = true;
        }

        createMarkers(file, convertValidationMessages(valReport.getValidationMessages()));
        //createMarkers(file, validatormanager.getWarningList(), WARNING_MARKER);
        
        //file.setSessionProperty(ValidationMessage.ERROR_MESSAGE_MAP_QUALIFIED_NAME, valReport.getNestedMessages());
        file.setSessionProperty(org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage.ERROR_MESSAGE_MAP_QUALIFIED_NAME, convertNestedValidationMessages(valReport.getNestedMessages()));
      }
    };

    try
    {
      ResourcesPlugin.getWorkspace().run(op, null);

      if (showDialog)
      {
        showDialog(validationOutcome);
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
  
  /**
   * Convert WSDL validation messages to validation framework messages.
   * 
   * @param messages The WSDL validation messages to convert.
   * @return The converted validation messages.
   */
  private org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage[] convertValidationMessages(IValidationMessage[] messages)
  {
  	int numMessages = messages.length;
  	org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage[] convertedMessages = new org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage[numMessages];
  	
  	for(int i = 0; i < numMessages; i++)
  	{
  	  IValidationMessage mess = messages[i];
      
      org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage convertMess = null;
      if (mess instanceof ValidationMessageImpl)
      {   String errorKey = ((ValidationMessageImpl)mess).getErrorKey();
          Object[] messageArgs = ((ValidationMessageImpl)mess).getMessageArguments();
          convertMess = new org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage(mess.getMessage(), mess.getLine(), mess.getColumn(), mess.getURI(), errorKey, messageArgs);
      }
      else
      {
         convertMess = new org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage(mess.getMessage(),mess.getLine(),mess.getColumn(), mess.getURI());
      }
  	  if(mess.getSeverity() == IValidationMessage.SEV_WARNING)
	  {
	  	convertMess.setSeverity(org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage.SEV_LOW);
	  }
	  else
	  {
	  	convertMess.setSeverity(org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage.SEV_HIGH);
	  }
  	  
  	  // Convert any nested messages.
  	  List nestedMessages = mess.getNestedMessages();
  	  if(nestedMessages != null && !nestedMessages.isEmpty())
  	  {
  	  	Iterator nestedIter = nestedMessages.iterator();
  	    while(nestedIter.hasNext())
        {
          IValidationMessage nestedMess = (IValidationMessage)nestedIter.next();
    	  org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage convertNestedMess = new org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage(nestedMess.getMessage(),nestedMess.getLine(),nestedMess.getColumn(), nestedMess.getURI());
    	  if(nestedMess.getSeverity() == IValidationMessage.SEV_WARNING)
    	  {
    	  	convertNestedMess.setSeverity(org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage.SEV_LOW);
    	  }
    	  else
    	  {
    	  	convertNestedMess.setSeverity(org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage.SEV_HIGH);
    	  }
    	  convertMess.addNestedMessage(convertNestedMess);
        }
  	  }
  	  convertedMessages[i] = convertMess;
  	}
  	return convertedMessages;
  }
  
  /**
   * Convert the nested messages hashmap.
   * 
   * @param nestedMessages The nested messages hashmap to convert.
   * @return A hashmap with the converted validation messages.
   */
  private HashMap convertNestedValidationMessages(HashMap nestedMessages)
  {
  	HashMap convertedMap = new HashMap();
  	
  	Set keySet = nestedMessages.keySet();
  	Iterator keysIter = keySet.iterator();
  	while(keysIter.hasNext())
  	{
  	  String key = (String)keysIter.next();
  	  IValidationMessage message = (IValidationMessage)nestedMessages.get(key);
  	  org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage[] convertedMessage = convertValidationMessages(new IValidationMessage[]{message});
  	  
  	  convertedMap.put(key, convertedMessage[0]);
  	}
  	return convertedMap;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.jface.action.IAction#run()
   */
//  public void run()
//  {
//    // Only run the validation if the file exists and is available.
//    if (fileIsOK(file))
//    {
//      if (showDialog)
//      {
//        // Check if the file is dirty - prompts user to save.
//        checkIfFileDirty(file);
//      }
//      super.run();
//    }
//  }

  /**
   * Test whether the file given is OK to use. A file is OK to use if 1. It is
   * not null 2. It exists. 3. The project containing the file is accessible.
   * 
   * @param file The file to check to see if it is OK to validate.
   * @return True if the file is OK to validate, false otherwise.
   */
//  protected boolean fileIsOK(IFile file)
//  {
//    if (file != null && file.exists() && file.getProject().isAccessible())
//    {
//      return true;
//    }
//    return false;
//  }

  /**
   * Check if the file is dirty. A file is dirty if there is an open editor for
   * the file that contains changes that haven't been saved.
   * 
   * @param file The file to check to see if it is dirty.
   */
//  protected void checkIfFileDirty(IFile file)
//  {
//    IEditorPart[] dirtyEditors = ValidateWSDLPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getActivePage().getDirtyEditors();
//
//    int numeditors = dirtyEditors.length;
//    for (int i = 0; i < numeditors; i++)
//    {
//      IEditorInput editorInput = dirtyEditors[i].getEditorInput();
//      if (editorInput instanceof FileEditorInput)
//      {
//        FileEditorInput fileEditorInput = (FileEditorInput) editorInput;
//        if (fileEditorInput.getFile().equals(file))
//        {
//          String message = ValidateWSDLPlugin.getInstance().getString(_UI_SAVE_DIRTY_FILE_MESSAGE);
//          String title = ValidateWSDLPlugin.getInstance().getString(_UI_SAVE_DIRTY_FILE_TITLE);
//          if (MessageDialog.openQuestion(Display.getDefault().getActiveShell(), title, message))
//          {
//            dirtyEditors[i].doSave(null);
//          }
//          // There can only be one open editor/file so we can break.
//          break;
//        }
//      }
//
//    }
//  }

  /**
   * Create a marker on the file of the indicated type for each
   * ValidationMessage in the array.
   * 
   * @param iFile
   *          The file to add the markers to.
   * @param valMessages
   *          The array of messages to add as markers.
   */
//  public void createMarkers(IFile iFile, ValidationMessage[] valMessages)
//  {
//    if (!fileIsOK(iFile))
//    {
//      return;
//    }
//    int numValMessages = valMessages.length;
//    for (int i = 0; i < numValMessages; i++)
//    {
//      ValidationMessage validationMessage = valMessages[i];
//
//      int line = validationMessage.getLine();
//      int column = validationMessage.getColumn();
//      String message = validationMessage.getMessage();
//      int severity = validationMessage.getSeverity();
//      IMarker marker = null;
//      
//      boolean hasNestedErrors = false;
//      List nestederrors = validationMessage.getNestedMessages();
//      if(nestederrors != null && !nestederrors.isEmpty())
//      {
//        hasNestedErrors = true;
//        message += ValidateWSDLPlugin.getInstance().getString(_UI_REF_FILE_ERROR_MESSAGE); 
//      }
//      if (severity == ValidationMessage.SEV_ERROR)
//      {
//        marker = getOrCreateReporter().addErrorMessage(iFile, message, line, column);
//      }
//      else if (severity == ValidationMessage.SEV_WARNING)
//      {
//        marker = getOrCreateReporter().addWarningMessage(iFile, message, line, column);
//      }
//      
//      if (hasNestedErrors && marker != null)
//      {
//        try
//        {
//          marker.setAttribute("groupName", REFERENCED_FILE_ERROR_OPEN + validationMessage.getURI() + REFERENCED_FILE_ERROR_CLOSE);
//          marker.setAttribute(IMarker.DONE, true);
//        }
//        catch(CoreException e)
//        {
//        }
//      }
//      
//    }
//  }

  /**
   * Show a dialog containing the status of the validation. Will display valid
   * or invalid depending on whether there are errors or not.
   * 
   * @param validationOutcome
   *          The outcome of the validation.
   */
  public void showDialog(ValidationOutcome validationOutcome)
  {
    String title, message;
    if (validationOutcome.isValid)
    {
      if (validationOutcome.hasMessages)
      {
        showProblemsView();
        title = ValidateWSDLPlugin.getInstance().getString("_VALIDATION_SUCCEEDED");
        message = ValidateWSDLPlugin.getInstance().getString("_UI_THE_WSDL_FILE_IS_VALID_WITH_WARNINGS");
        MessageDialog.openWarning(Display.getDefault().getActiveShell(), title, message);
      }
      else
      {
        title = ValidateWSDLPlugin.getInstance().getString("_VALIDATION_SUCCEEDED");
        message = ValidateWSDLPlugin.getInstance().getString("_UI_THE_WSDL_FILE_IS_VALID");
        MessageDialog.openInformation(Display.getDefault().getActiveShell(), title, message);
      }

    }
    else
    {
      if (validationOutcome.isWSDLValid)
      {
        title = ValidateWSDLPlugin.getInstance().getString("_VALIDATION_FAILED");
        message = ValidateWSDLPlugin.getInstance().getString("_UI_THE_WSDL_FILE_IS_VALID_WSDL11");
      }
      else
      {
        title = ValidateWSDLPlugin.getInstance().getString("_VALIDATION_FAILED");
        message = ValidateWSDLPlugin.getInstance().getString("_UI_THE_WSDL_FILE_IS_NOT_VALID");
      }
      showProblemsView();
      MessageDialog.openError(Display.getDefault().getActiveShell(), title, message);
    }

  }
  
  /**
   * Show the problems view if it is not already visible.
   */
//  protected void showProblemsView()
//  {
//    IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
//    IWorkbenchPage page = dw.getActivePage();
//    IWorkbenchPart activePart = page.getActivePart();
//    try
//    {
//      if (page != null)
//      {
//        page.showView("org.eclipse.ui.views.ProblemView");
//      }
//    }
//    catch (PartInitException e)
//    {
//    }
//    page.activate(activePart);
//  }

  /**
   * If a reporter doesn't exist creates it or uses the reporter already
   * created.
   * 
   * @return a reporter
   */
//  protected IReporter getOrCreateReporter()
//  {
//    if (reporter == null)
//    {
//      reporter = new WorkbenchReporter(file.getProject(), new NullProgressMonitor());
//    }
//    return reporter;
//  }

  /**
   * Clear all the markers on the given resource generated by this validator.
   * 
   * @param resource -
   *          the resrouce to clear all the markers from
   */
//  public void clearMarkers(IResource resource)
//  {
//    getOrCreateReporter().removeAllMessages(resource);
//  }

  protected class ValidationOutcome
  {
    public boolean isValid = true;

    public boolean isWSDLValid = true;

    public boolean hasMessages = false;

    public ValidationOutcome()
    {
    }
  }

  public void setInputStream(InputStream inputStream)
  {  this.inputStream = inputStream;
  }
  
  /**
   * Set extra attributes in the IMessage to provide information on what should be "squiggled"
   * @param valMess the ValidationMessage corresponding to this error
   * @param message the IMessage to set the attributes for
   */
  protected void addInfoToMessage(org.eclipse.wst.xml.core.internal.validation.core.ValidationMessage valMess, IMessage message)
  {   if (valMess.getKey() != null)
      {
          XMLMessageInfoHelper helper = new XMLMessageInfoHelper();
          String[] squiggleInfo = helper.createMessageInfo(valMess.getKey(), valMess.getMessageArguments());
      
          message.setAttribute(COLUMN_NUMBER_ATTRIBUTE, new Integer(valMess.getColumnNumber()));
          message.setAttribute(SQUIGGLE_SELECTION_STRATEGY_ATTRIBUTE, squiggleInfo[0]);
          message.setAttribute(SQUIGGLE_NAME_OR_VALUE_ATTRIBUTE, squiggleInfo[1]);
      }
  }

}