/*******************************************************************************
 * Copyright (c) 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.xsd.ui.internal.dialogs.types.xsd;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.common.uriresolver.internal.util.URIHelper;
import org.eclipse.wst.xsd.ui.internal.actions.CreateElementAction;
import org.eclipse.wst.xsd.ui.internal.actions.DOMAttribute;
import org.eclipse.wst.xsd.ui.internal.dialogs.types.xml.XMLComponentSpecification;
import org.eclipse.wst.xsd.ui.internal.refactor.rename.XSDExternalFileCleanup;
import org.eclipse.wst.xsd.ui.internal.util.TypesHelper;
import org.eclipse.wst.xsd.ui.internal.util.XSDDOMHelper;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDInclude;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaContent;
import org.eclipse.xsd.XSDSchemaDirective;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDParser;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class XSDSetTypeHelper {
    private XSDSchema xsdSchema;
    private IFile currentIFile;
    
    public XSDSetTypeHelper(IFile iFile, XSDSchema schema) {
        currentIFile = iFile;
        xsdSchema = schema;
    }

    public void setType(Element element, String property, XMLComponentSpecification spec) {
        addImportIfNecessary(element, spec);        
        String typeObject = getPrefixedTypeName(spec);
        
        // Get the previous type --> previousStringType
        String previousStringType = "";
        Attr attr = element.getAttributeNode(property);
        if (attr != null) {
            attr.getValue();
        }

        if (!XSDDOMHelper.inputEquals(element, XSDConstants.UNION_ELEMENT_TAG, false))
        {
            if (spec != null && spec.getTagPath().equals("**anonymous**"))
            {
              if (spec.getTagPath().equals("ANONYMOUS_SIMPLE_TYPE"))
              {
                if (!previousStringType.equals("**anonymous**"))
                {
                  updateElementToAnonymous(element, XSDConstants.SIMPLETYPE_ELEMENT_TAG);
                }
              }
              else
              {
                if (!previousStringType.equals("**anonymous**"))
                {
                  updateElementToAnonymous(element, XSDConstants.COMPLEXTYPE_ELEMENT_TAG);
                }
              }
              // element.removeAttribute(XSDConstants.TYPE_ATTRIBUTE);
              element.removeAttribute(property);
            }
            else
            {
              XSDDOMHelper.updateElementToNotAnonymous(element);
              //element.setAttribute(XSDConstants.TYPE_ATTRIBUTE, typeObject.toString());
              element.setAttribute(property, typeObject.toString());
            }
        }
    }
    
    public void addImportIfNecessary(Element element, XMLComponentSpecification spec) {
        
        // Get the new type --> typeObject
        if (spec != null) {
            String itemType = spec.getTagPath();
           
            if (!itemType.equals("BUILT_IN_SIMPLE_TYPE")) {
                // Do an actual import if needed
                XSDParser parser = new XSDParser();
                parser.parse(spec.getFileLocation());
                XSDSchema schema = parser.getSchema();
                String tns = schema.getTargetNamespace();
                
                boolean exists = false;
                // Check if the type is defined in the 'current' file itself.
                String currentFile = getNormalizedLocation(xsdSchema.getSchemaLocation());
                IPath currentFilePath = new Path(currentFile);
                if (currentFilePath.equals(new Path(spec.getFileLocation()))) {
                    exists = true;
                }

                if (!exists) {
                    if (tns.equals(xsdSchema.getTargetNamespace())) {
                        // Check if the schema is in a redefine/include
                        List existingList = getXSDIncludes();
                        existingList.addAll(getXSDRedefines());
                        Iterator it = existingList.iterator();
                        while (it.hasNext()) {
                            XSDSchemaDirective existingSchema = (XSDSchemaDirective) it.next();
                            String normalizedFile = getNormalizedLocation(existingSchema.getResolvedSchema().getSchemaLocation());
                            String normalizedSpec = spec.getFileLocation();
                            
                            if (normalizedFile.equals(normalizedSpec)) {
                                // Found and existing one
                                exists = true;
                            }
                        }                        
                    }
                    else {
                        // Check if the schema is in a import
                        List existingList = getXSDImports();
                        Iterator it = existingList.iterator();
                        while (it.hasNext()) {
                            XSDSchemaDirective existingSchema = (XSDSchemaDirective) it.next();
                            String normalizedFile = getNormalizedLocation(existingSchema.getResolvedSchema().getSchemaLocation());
                            String normalizedSpec = spec.getFileLocation();

                            if (normalizedFile.equals(normalizedSpec)) {
                                // Found and existing one
                                exists = true;
                            }
                        }                        
                    }
                }
                
                if (!exists) {
                    doImport(spec.getFileLocation(), schema);
                }
            }
        }
    }
    
    /*
     * Return the prefixed type name for the type described by the given
     * XMLComponentSpecification object.
     * If the type described is a Built-in type, do not add the prefix
     */
    public String getPrefixedTypeName(XMLComponentSpecification spec) {
        String typeObject = (String) spec.getAttributeInfo("name");
        
        TypesHelper typesHelper = new TypesHelper(xsdSchema); // ???? Is this correct?
        List prefixedNames = typesHelper.getPrefixedNames(spec.getTargetNamespace(), typeObject);
        if (prefixedNames.size() > 0) {
            // Grab the first prefixed name
            typeObject = (String) prefixedNames.get(0);
        }

        return typeObject;
    }
    
    private void updateElementToAnonymous(Element element, String xsdType) {
        String prefix = element.getPrefix();
        prefix = (prefix == null) ? "" : (prefix + ":");
        XSDDOMHelper.updateElementToNotAnonymous(element);
        Element childNode = null;
        if (xsdType.equals(XSDConstants.COMPLEXTYPE_ELEMENT_TAG)) {
            childNode = element.getOwnerDocument().createElementNS(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001, prefix + XSDConstants.COMPLEXTYPE_ELEMENT_TAG);
        }
        else if (xsdType.equals(XSDConstants.SIMPLETYPE_ELEMENT_TAG)) {
            childNode = element.getOwnerDocument().createElementNS(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001, prefix + XSDConstants.SIMPLETYPE_ELEMENT_TAG);
        }
        
        if (childNode != null) {
            XSDDOMHelper helper = new XSDDOMHelper();
            Node annotationNode = helper.getChildNode(element, XSDConstants.ANNOTATION_ELEMENT_TAG);
            if (annotationNode == null) {
                Node firstChild = element.getFirstChild();
                element.insertBefore(childNode, firstChild);
            } else {
                Node nextSibling = annotationNode.getNextSibling();
                element.insertBefore(childNode, nextSibling);
            }
            XSDDOMHelper.formatChild(childNode);
        }
    }

    // TODO: We shouldn't need to pass in IPath externalSchemaPath.
    private void doImport(String externalSchemaPath, XSDSchema externalSchema) {
        // Determine schemaLocation
        String locationAttribute = URIHelper.getRelativeURI(externalSchemaPath, currentIFile.getLocation().toOSString());
        
        boolean isInclude = false;
        if (externalSchema.getTargetNamespace().equals(xsdSchema.getTargetNamespace())) {
            isInclude = true;
        }
        
        if (externalSchema != null) { // In case we have problems loading the file.... we should display an error message.
                Element newElement;
                if (isInclude) {                
                    List attributes = new ArrayList();
                    attributes.add(new DOMAttribute(XSDConstants.SCHEMALOCATION_ATTRIBUTE, locationAttribute));
                    newElement = createElement(XSDConstants.INCLUDE_ELEMENT_TAG, attributes);
                }
                else if (!isInclude) {
                    List attributes = new ArrayList();
                    attributes.add(new DOMAttribute(XSDConstants.NAMESPACE_ATTRIBUTE, externalSchema.getTargetNamespace()));
                    attributes.add(new DOMAttribute(XSDConstants.SCHEMALOCATION_ATTRIBUTE, locationAttribute));
                    newElement = createElement(XSDConstants.IMPORT_ELEMENT_TAG, attributes);
                    handleImportNS(newElement, externalSchema);
                }
        }
    }

    private void handleImportNS(Element importElement, XSDSchema externalSchema) {
        String namespace = externalSchema.getTargetNamespace();
        if (namespace == null) namespace = "";

        XSDImport xsdImport = (XSDImport) xsdSchema.getCorrespondingComponent(importElement);
        xsdImport.setResolvedSchema(externalSchema);
        
        java.util.Map map = xsdSchema.getQNamePrefixToNamespaceMap();
        
//        System.out.println("changed Import Map is " + map.values());
//        System.out.println("changed import Map keys are " + map.keySet());

        // Referential integrity on old import
        // How can we be sure that if the newlocation is the same as the oldlocation
        // the file hasn't changed
                
        XSDSchema referencedSchema = xsdImport.getResolvedSchema();
        if (referencedSchema != null)
        {
          XSDExternalFileCleanup cleanHelper = new XSDExternalFileCleanup(referencedSchema);
          cleanHelper.visitSchema(xsdSchema);
        }
         
        Element schemaElement = xsdSchema.getElement();

        // update the xmlns in the schema element first, and then update the import element next
        // so that the last change will be in the import element.  This keeps the selection
        // on the import element
        TypesHelper helper = new TypesHelper(externalSchema);
        String prefix = helper.getPrefix(namespace, false);
        
        if (map.containsKey(prefix))
        {
          prefix = null;
        }

        if (prefix == null || (prefix !=null && prefix.length() == 0))
        {
          StringBuffer newPrefix = new StringBuffer("pref");  //$NON-NLS-1$
          int prefixExtension = 1;
          while (map.containsKey(newPrefix.toString()) && prefixExtension < 100)
          {
            newPrefix = new StringBuffer("pref" + String.valueOf(prefixExtension));
            prefixExtension++;
          }
          prefix = newPrefix.toString();
        }

        if (namespace.length() > 0)
        {
          // if ns already in map, use its corresponding prefix
          if (map.containsValue(namespace))
          {
            TypesHelper typesHelper = new TypesHelper(xsdSchema);
            prefix = typesHelper.getPrefix(namespace, false);
          }
          else // otherwise add to the map
          {
            schemaElement.setAttribute("xmlns:"+prefix, namespace);
          }
        }


//        System.out.println("changed Import Map is " + map.values());
//        System.out.println("changed import Map keys are " + map.keySet());
    }
    
    private Element createElement(String elementTag, List attributes) {
        Node relativeNode = XSDDOMHelper.getNextElementNode(xsdSchema.getElement().getFirstChild());
        
        CreateElementAction action = new CreateElementAction("");
        action.setElementTag(elementTag);
        action.setAttributes(attributes);
        action.setParentNode(xsdSchema.getElement());
        action.setRelativeNode(relativeNode);
        action.setXSDSchema(xsdSchema);
        return action.createAndAddNewChildElement();
    }

    private String getNormalizedLocation(String location) {
        try {
            URL url = new URL(location);
            URL resolvedURL = Platform.resolve(url);
            location = resolvedURL.getPath();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
        return location; 
      }
    
    private List getXSDImports() {
        List imports = new ArrayList();
        
        Iterator contents = xsdSchema.getContents().iterator();
        while (contents.hasNext()) {
            XSDSchemaContent content = (XSDSchemaContent) contents.next();
            if (content instanceof XSDImport) {
                imports.add(content);             
            }
        }
        
        return imports;
    }
    
    private List getXSDIncludes() {
        List includes = new ArrayList();
        
        Iterator contents = xsdSchema.getContents().iterator();
        while (contents.hasNext()) {
            XSDSchemaContent content = (XSDSchemaContent) contents.next();
            if (content instanceof XSDInclude) {
                includes.add(content);            
            }
        }
        
        return includes;
    }

    private List getXSDRedefines() {
        List includes = new ArrayList();
        
        Iterator contents = xsdSchema.getContents().iterator();
        while (contents.hasNext()) {
            XSDSchemaContent content = (XSDSchemaContent) contents.next();
            if (content instanceof XSDRedefine) {
                includes.add(content);            
            }
        }
        
        return includes;
    }

}