/**
 *
 * Copyright 2004 The Apache Software Foundation
 *
 *  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.apache.ws.scout.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.xml.registry.JAXRException;
import javax.xml.registry.infomodel.ClassificationScheme;
import javax.xml.registry.infomodel.Concept;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.scout.registry.infomodel.ClassificationSchemeImpl;
import org.apache.ws.scout.registry.infomodel.ConceptImpl;
import org.apache.ws.scout.registry.infomodel.InternationalStringImpl;
import org.apache.ws.scout.registry.infomodel.KeyImpl;

/**
 * Helper class that deals with predefined enumerations
 *
 * @author Anil Saldhana  <anil@apache.org>
 * @author Kurt Stam <kstam@apache.org>
 * 
 */
public class EnumerationHelper
{
    private static Log log = LogFactory.getLog(EnumerationHelper.class);
   

    private final static String UDDI_ORG_TYPES		      = "uuid:C1ACF26D-9672-4404-9D70-39B756E62AB4"; 
    private final static String OBJECT_TYPE                   = "ObjectType";
    private final static String ASSOCIATION_TYPE              = "AssociationType";
    private final static String URL_TYPE                      = "URLType";
    private final static String PHONE_TYPE                    = "PhoneType";
    private final static String POSTAL_ADDRESS_ATTRIBUTES_STR = "PostalAddressAttributes";
    private final static String[] TYPES = {OBJECT_TYPE, ASSOCIATION_TYPE, URL_TYPE, PHONE_TYPE, POSTAL_ADDRESS_ATTRIBUTES_STR};
    
    private final static String[] OBJECT_TYPES = {
         "ExternalLink","Package","ExternalId","Association","Classification","Concept",
         "AuditableEvent","User","Organization","CPA","CPP","Service","ServiceBinding","Process","WSDL",
         "ExtrinsicObj","Organization","User"};
    private final static String[] ASSOCIATION_TYPES = {
         "RelatedTo","ExternallyLinks","Contains","Extends","Implements",
         "InstanceOf","Supersedes","Uses","HasMember","EquivalentTo","HasChild","HasParent","Replaces",
         "ResponsibleFor","SubmitterOf"};
    private final static String[] URL_TYPES = {
         "HTTP","HTTPS","SMTP","FAX","PHONE","OTHER"};
    private final static String[] PHONE_TYPES = {
         "Office","Home","Mobile","Beeper","FAX"};
    private final static String[] POSTAL_ADDRESS_ATTRIBUTES = {
         "StreetNumber","Street","City","State","PostalCode","Country"};
    
    private final static ArrayList<String> TYPES_LIST                     = new ArrayList<String>(Arrays.asList(TYPES));
    private final static ArrayList<String> OBJECT_TYPES_LIST              = new ArrayList<String>(Arrays.asList(OBJECT_TYPES));
    private final static ArrayList<String> ASSOCIATION_TYPES_LIST         = new ArrayList<String>(Arrays.asList(ASSOCIATION_TYPES));
    private final static ArrayList<String> URL_TYPES_LIST                 = new ArrayList<String>(Arrays.asList(URL_TYPES));
    private final static ArrayList<String> PHONE_TYPES_LIST               = new ArrayList<String>(Arrays.asList(PHONE_TYPES));
    private final static ArrayList<String> POSTAL_ADDRESS_ATTRIBUTES_LIST = new ArrayList<String>(Arrays.asList(POSTAL_ADDRESS_ATTRIBUTES));

    private static Map<String,ArrayList<String>> typesMap = new HashMap<String,ArrayList<String>>();
    static {
        typesMap.put(OBJECT_TYPE                  ,OBJECT_TYPES_LIST);
        typesMap.put(ASSOCIATION_TYPE             ,ASSOCIATION_TYPES_LIST);
        typesMap.put(URL_TYPE                     , URL_TYPES_LIST);
        typesMap.put(PHONE_TYPE                   , PHONE_TYPES_LIST);
        typesMap.put(POSTAL_ADDRESS_ATTRIBUTES_STR, POSTAL_ADDRESS_ATTRIBUTES_LIST);
    }
    
    public static Concept getConceptByPath( String path)
    throws IllegalArgumentException, JAXRException
    {
        //Lets tokenize the path
        StringTokenizer tokenizer = new StringTokenizer(path,"/");
        String firstToken = null;
        String secondToken = null;
        
        if(tokenizer.hasMoreTokens())
        {
           firstToken = tokenizer.nextToken();
           if (tokenizer.hasMoreTokens()) {
               secondToken = tokenizer.nextToken();
               if (tokenizer.hasMoreTokens()) {
                   log.warn("Looking for 2 tokens. " + tokenizer.nextToken() + " will be ignored");
               }
           } else {
               throw new IllegalArgumentException("Expected two token separated with a forward slash (/)");
           }
        } else {
            throw new IllegalArgumentException("Expected two token separated with a forward slash (/)");
        }
        return createConcept(firstToken, secondToken) ;
    }

    /**
     * 
     * @param firstToken
     * @param secondToken
     * @return Concept
     * @throws JAXRException
     */
    private static  Concept createConcept(String firstToken, String secondToken)
            throws JAXRException, IllegalArgumentException
    {
        if (!TYPES_LIST.contains(firstToken)) throw new IllegalArgumentException("Expected the path to " +
                "start with one of " + Arrays.toString(TYPES));
        
        //get the predefined classificationscheme
        ClassificationScheme cs = new ClassificationSchemeImpl(null);
        cs.setName(new InternationalStringImpl(firstToken));
        cs.setKey(new KeyImpl(firstToken));

        ArrayList<String> conceptStrings = typesMap.get(firstToken);
        if (!conceptStrings.contains(secondToken)) throw new IllegalArgumentException("Expected the path to " +
                "end with one of " + Arrays.toString(conceptStrings.toArray()));
                
        Concept concept = new ConceptImpl(null);
        concept.setName(new InternationalStringImpl(secondToken.toLowerCase()));
        concept.setValue(secondToken);
        concept.setKey(new KeyImpl(UDDI_ORG_TYPES));
        ((ConceptImpl)concept).setScheme(((ClassificationSchemeImpl)cs));
        return concept;
    }
}
