package com.avaya.mgmt.smgr.webservice.jaxb.util;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

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

import com.avaya.coreservice.um.xml.Users;
import com.avaya.coreservice.um.xml.XmlUser;

/**
 * 
 * @author
 * 
 */
public class UserMgmtClientUtil
{

	/**
	 * 
	 */
	private final static String[] contextPathList = new String[]
	{ "com.avaya.coreservice.um.xml",
			"com.avaya.iptcm.eps.upm.bulkimportexport.jaxbgen.station",
			"com.avaya.asm.mgmt.upmcomprof.bulkimport.genxml" };

	/**
	 * 
	 * @param users
	 * @return
	 * @throws JAXBException
	 * @throws IOException
	 */
	public static String toStringUser(final Users users) throws JAXBException,
			IOException
	{
		if (null == users)
		{
			return "";
		}
		final JAXBContext jaxbContext = JAXBContext
				.newInstance(convert2ContextPath(contextPathList));
		final Marshaller marshaller = jaxbContext.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
				"http://xml.avaya.com/schema/import userimport.xsd");
		marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper",
				new NamespacePrefixMapperImpl());
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		final StringWriter stringWriter = new StringWriter();
		marshaller.marshal(users, stringWriter);
		stringWriter.flush();
		stringWriter.close();
		String xmlString = stringWriter.getBuffer().toString()
				.replaceAll("<user>", "<tns:user>")
				.replaceAll("</user>", "</tns:user>");
		xmlString = xmlString
				.replaceAll(
						"\"ipt:xmlStationProfile\"",
						"\"ipt:xmlStationProfile\" xmlns:ipt=\"http://xml.avaya.com/schema/import_csm_cm\"");

		return xmlString;
	}

	/**
	 * 
	 * @param xmlUsers
	 * @return
	 * @throws JAXBException
	 * @throws IOException
	 */
	public static List<String> getLoginNames(final String xmlUsers)
			throws JAXBException, IOException
	{
		final List<String> loginNames = new ArrayList<String>();
		if (null == xmlUsers)
		{
			return loginNames;
		}
		final Users users = getUsers(xmlUsers);
		if (null == users)
		{
			return loginNames;
		}
		final List<XmlUser> xmlUserList = users.getUser();
		for (XmlUser xmlUser : xmlUserList)
		{
			loginNames.add(xmlUser.getLoginName());
		}
		return loginNames;
	}

	/**
	 * 
	 * @param entityXmlData
	 * @return
	 * @throws JAXBException
	 * @throws IOException
	 */
	public static Users getUsers(final String entityXmlData)
			throws JAXBException, IOException
	{

		if (null == entityXmlData || entityXmlData.trim().length() < 1)
		{
			return null;
		}
		final String xmlUserData = entityXmlData.replaceAll("<tns:user>",
				"<user>").replaceAll("</tns:user>", "</user>");
		if (xmlUserData.indexOf("No data") != -1)
		{
			return null;
		}
		final JAXBContext jaxbContext = JAXBContext
				.newInstance(convert2ContextPath(contextPathList));
		final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
		final StringReader stringReader = new StringReader(xmlUserData);
		final Object object = unmarshaller.unmarshal(stringReader);
		try
		{
			if (object instanceof Users)
			{
				return (Users) object;
			}
		} finally
		{
			if (null != stringReader)
			{
				// stringReader.close();
			}
		}
		return null;
	}

	/**
	 * 
	 * @param contextPathList
	 * @return
	 */
	private static String convert2ContextPath(final String[] contextPathList)
	{
		if (null == contextPathList || contextPathList.length < 1)
		{
			return "";
		}
		final StringBuffer nameSpaceContext = new StringBuffer();
		for (String contextPath : contextPathList)
		{
			if (nameSpaceContext.length() < 1)
			{
				nameSpaceContext.append(contextPath);
				continue;
			}
			nameSpaceContext.append(":" + contextPath);
		}
		return nameSpaceContext.toString();
	}

	/**
	 * 
	 * @param criteriaCondition
	 * @return
	 */
	public static String createQuery(final String criteriaCondition)
	{
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer
				.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
						+ "<tns:management-webservice-criteria"
						+ " xmlns:tns=\"http://www.avaya.com/mgmt-web-criteria/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
						+ " xsi:schemaLocation=\"http://www.avaya.com/mgmt-web-criteria/ mgmt-web-criteria.xsd \">\n"
						+ "<criterialist>\n");
		List<CriteriaDS> criteriaList = getCriteriaCondition(criteriaCondition);
		for (CriteriaDS criteriaDS : criteriaList)
		{
			stringBuffer.append("<criteria>\n" + "<propertyname>");
			stringBuffer.append(criteriaDS.getPropertyName());
			stringBuffer.append("</propertyname>\n" + "<operator>");
			stringBuffer.append(criteriaDS.getOperator());
			stringBuffer.append("</operator>\n" + "<value>");
			stringBuffer.append(criteriaDS.getValue());
			stringBuffer.append("</value>\n" + "<restriction>");
			stringBuffer.append(criteriaDS.getRestriction());
			stringBuffer.append("</restriction>\n" + "</criteria>\n");
		}
		stringBuffer.append("</criterialist>\n"
				+ "</tns:management-webservice-criteria>\n");
		System.out.println("QUERY : " + stringBuffer.toString());
		return stringBuffer.toString().replaceAll("&", "&amp;")
				.replaceAll("<", "&lt;").replaceAll(">", "&gt;")
				.replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
	}

	/**
	 * 
	 * @param loginNames
	 * @return
	 */
	public static String createDeleteXmlData(final List<String> loginNames,
			final String deleteType)
	{
		final StringBuffer stringBuffer = new StringBuffer();
		stringBuffer
				.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
						+ "<tns:deleteUsers xmlns:tns=\"http://xml.avaya.com/schema/bulkdelete\""
						+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
						+ " xsi:schemaLocation=\"http://xml.avaya.com/schema/bulkdelete UserProfileSchemaDefinitionForBulkDelete.xsd \">\n"
						+ " <tns:deleteType>" + deleteType
						+ "</tns:deleteType>\n");
		for (String loginName : loginNames)
		{
			stringBuffer.append("<tns:user>\n" + "<tns:loginName>" + loginName
					+ "</tns:loginName>\n" + "</tns:user>\n");
		}
		stringBuffer.append("</tns:deleteUsers>\n");
		return stringBuffer.toString();
	}

	
	/**
	 * 
	 * @param users
	 * @return
	 * @throws JAXBException
	 * @throws IOException
	 */
	public static String createDeltaXMLData(final Users users) throws JAXBException,
			IOException
	{
		if (null == users)
		{
			return "";
		}
		final JAXBContext jaxbContext = JAXBContext
				.newInstance(convert2ContextPath(contextPathList));
		final Marshaller marshaller = jaxbContext.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
				"http://xml.avaya.com/schema/deltaImport userdeltaimport.xsd");
		marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper",
				new NamespacePrefixMapperImpl());
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		final StringWriter stringWriter = new StringWriter();
		marshaller.marshal(users, stringWriter);
		stringWriter.flush();
		stringWriter.close();
		String xmlString = stringWriter.getBuffer().toString()
				.replaceAll("<user>", "<delta:userDelta>")
				.replaceAll("</user>", "</delta:userDelta>")
				.replaceAll("tns:users", "delta:deltaUserList")
				.replaceAll("\"ipt:xmlStationProfile\"", "\"ipt:xmlStationProfile\" xmlns:ipt=\"http://xml.avaya.com/schema/import_csm_cm\"");
		
		/*
		xmlString = xmlString
				.replaceAll(
						"\"ipt:xmlStationProfile\"",
						"\"ipt:xmlStationProfile\" xmlns:ipt=\"http://xml.avaya.com/schema/import_csm_cm\"");
		
		xmlString = xmlString
				.replaceAll(
						"\"asm:SessionManagerCommProfXML\"",
						"\"asm:SessionManagerCommProfXML\" xmlns:asm=\"http://xml.avaya.com/schema/import_sessionmanager\"");
		*/

		return xmlString;
	}
	
	
	/**
	 * 
	 * @param loginName
	 * @return
	 */
	public static String createDeleteXmlData(final String loginName,
			final String deleteType)
	{
		final StringBuffer stringBuffer = new StringBuffer();
		stringBuffer
				.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
						+ "<tns:deleteUsers xmlns:tns=\"http://xml.avaya.com/schema/bulkdelete\""
						+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
						+ " xsi:schemaLocation=\"http://xml.avaya.com/schema/bulkdelete UserProfileSchemaDefinitionForBulkDelete.xsd \">\n"
						+ " <tns:deleteType>" + deleteType
						+ "</tns:deleteType>\n");
		stringBuffer.append("<tns:user>\n" + "<tns:loginName>" + loginName
				+ "</tns:loginName>\n" + "</tns:user>\n");
		stringBuffer.append("</tns:deleteUsers>\n");
		return stringBuffer.toString();
	}

	/**
	 * 
	 * @param criteriaCondition
	 */
	public static int[] getRangeIndex(final String criteriaCondition)
	{
		final int[] indexes = new int[]
		{ 0, 0 };
		final List<CriteriaDS> criterList = getCriteriaCondition(criteriaCondition);
		for (CriteriaDS criteriaDS : criterList)
		{
			if (criteriaDS.getPropertyName().equalsIgnoreCase("startindex"))
			{
				indexes[0] = Integer.valueOf(criteriaDS.getValue());
			} else if (criteriaDS.getPropertyName().equalsIgnoreCase(
					"offsetindex"))
			{
				indexes[1] = Integer.valueOf(criteriaDS.getValue());
			}
		}
		return indexes;
	}

	/**
	 * 
	 * @param criterialist
	 * @return
	 */
	public static List<CriteriaDS> getCriteriaCondition(
			final String criterialist)
	{
		final List<CriteriaDS> criteriaCondition = new ArrayList<CriteriaDS>();
		final String[] criterias = criterialist.split("#");
		for (String criteria : criterias)
		{
			final String[] attr = criteria.split(":");
			if (attr.length != 4)
			{
				continue;
			}
			criteriaCondition.add(new CriteriaDS(attr[0], attr[1], attr[2],
					attr[3]));
		}
		return criteriaCondition;
	}
}

/**
 * 
 * @author
 * 
 */
class CriteriaDS
{

	private String propertyName;

	private String operator;

	private String value;

	private String restriction;

	/**
	 * 
	 * @param propertyName
	 * @param operator
	 * @param value
	 * @param restriction
	 */
	public CriteriaDS(final String propertyName, final String operator,
			final String value, final String restriction)
	{
		this.propertyName = propertyName;
		this.operator = operator;
		this.value = value;
		this.restriction = restriction;
	}

	public String getPropertyName()
	{
		return propertyName;
	}

	public void setPropertyName(String propertyName)
	{
		this.propertyName = propertyName;
	}

	public String getOperator()
	{
		return operator;
	}

	public void setOperator(String operator)
	{
		this.operator = operator;
	}

	public String getValue()
	{
		return value;
	}

	public void setValue(String value)
	{
		this.value = value;
	}

	public String getRestriction()
	{
		return restriction;
	}

	public void setRestriction(String restriction)
	{
		this.restriction = restriction;
	}
}
