/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  The ASF licenses this file to You
* 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.  For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.abdera.converter;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.abdera.converter.annotation.BaseURI;
import org.apache.abdera.converter.annotation.Charset;
import org.apache.abdera.converter.annotation.EntityTag;
import org.apache.abdera.converter.annotation.Language;
import org.apache.abdera.converter.annotation.LastModified;
import org.apache.abdera.converter.annotation.Slug;
import org.apache.abdera.converter.impl.StringConverter;
import org.apache.abdera.i18n.iri.IRI;
import org.apache.abdera.model.AtomDate;
import org.apache.abdera.model.Base;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Element;

@SuppressWarnings("unchecked")
public abstract class BaseConverter<T> 
  extends Converter<T> {
  
  protected abstract T create(ConversionContext context);
  
  protected void init(
    Object source, 
    ObjectContext objectContext, 
    ConversionContext context, 
    T dest) {}
  
  protected void finish(
    Object source, 
    ObjectContext objectContext, 
    ConversionContext context, 
    T dest) {}

  protected void process(
    Object source, 
    ObjectContext 
    objectContext, 
    ConversionContext context,
    Conventions conventions,
    T dest,
    AccessibleObject accessor) {}
  
  private Document getDocument(T obj) {
    if (obj == null) return null;
    Document doc = null;
    if (obj instanceof Document) {
      doc = (Document) obj;
    } else if (obj instanceof Element) {
      Element element = (Element) obj;
      Document parent = element.getDocument();
      Element root = parent.getRoot();
      if (root.equals(element)) doc = parent;
    }
    return doc;
  }
  
  @Override 
  public T convert(
    Object source, 
    ObjectContext objectContext,
    ConversionContext context) {    
      T dest = create(context);
      init(
        source, 
        objectContext, 
        context, 
        dest);
      Conventions conventions = 
        ((ConventionConversionContext)context)
          .getConventions();
      for (AccessibleObject accessor : objectContext.getAccessors()) {
        if (dest instanceof Base && 
            accessor.isAnnotationPresent(Language.class) || 
            Language.class.equals(conventions.matchConvention(accessor))) {
          Object value = eval(accessor,source);
          ObjectContext valueContext = new ObjectContext(value,source,accessor);
          StringConverter c = new StringConverter();
          StringBuffer buf = c.convert(value, valueContext, context);
          if (buf != null) {
            if (dest instanceof Document) ((Document)dest).setLanguage(buf.toString());
            else if (dest instanceof Element) ((Element)dest).setLanguage(buf.toString());
          }
        } else if (dest instanceof Base &&
            accessor.isAnnotationPresent(BaseURI.class) || 
            BaseURI.class.equals(conventions.matchConvention(accessor))) {
          
          Object value = eval(accessor,source);
          String iri = null;
          if (value instanceof URI) {
            iri = value.toString();
          } else if (value instanceof URL) {
            iri = value.toString();
          } else if (value instanceof IRI) {
            iri = value.toString();
          } else {
            ObjectContext valueContext = new ObjectContext(value,source,accessor);
            StringConverter c = new StringConverter();
            StringBuffer buf = c.convert(value, valueContext, context);
            iri = buf.toString();
          }
          if (iri != null) {
            if (dest instanceof Document) ((Document)dest).setBaseUri(iri);
            else if (dest instanceof Element) ((Element)dest).setBaseUri(iri);
          }
        } else if (accessor.isAnnotationPresent(Slug.class) || 
          Slug.class.equals(conventions.matchConvention(accessor))) {
            Object value = eval(accessor,source);
            ObjectContext valueContext = new ObjectContext(value,source,accessor);
            StringConverter c = new StringConverter();
            StringBuffer buf = c.convert(value, valueContext, context);
            Document doc = getDocument(dest);
            if (doc != null && buf != null) doc.setSlug(buf.toString());
        } else if (accessor.isAnnotationPresent(LastModified.class) || 
            LastModified.class.equals(conventions.matchConvention(accessor))) {
          Object value = eval(accessor,source);
          Document doc = getDocument(dest);
          if (doc != null) {
            if (value instanceof Date) {
              doc.setLastModified((Date)value);
            } else if (value instanceof Calendar) {
              Calendar cal = (Calendar)value;
              doc.setLastModified(cal.getTime());
            } else if (value instanceof Long) {
              Long l = (Long) value;
              doc.setLastModified(new Date(l.longValue()));
            } else if (value instanceof String) {
              doc.setLastModified(AtomDate.parse((String)value));
            } else {
              StringConverter s = new StringConverter();
              StringBuffer v = s.convert(source, objectContext, context);
              if (v != null) doc.setLastModified(AtomDate.parse(v.toString()));
            }
          }
        } else if (accessor.isAnnotationPresent(Charset.class) || 
            Charset.class.equals(conventions.matchConvention(accessor))) {
          Object value = eval(accessor,source);
          ObjectContext valueContext = new ObjectContext(value,source,accessor);
          StringConverter c = new StringConverter();
          StringBuffer buf = c.convert(value, valueContext, context);
          Document doc = getDocument(dest);
          if (doc != null && buf != null) doc.setCharset(buf.toString());
        } else if (accessor.isAnnotationPresent(EntityTag.class) || 
            EntityTag.class.equals(conventions.matchConvention(accessor))) {
          Document doc = getDocument(dest);
          if (doc != null) {
            Object value = eval(accessor,source);
            if (value instanceof org.apache.abdera.util.EntityTag) {
              doc.setEntityTag((org.apache.abdera.util.EntityTag)value);
            } else {
              ObjectContext valueContext = new ObjectContext(value,source,accessor);
              StringConverter c = new StringConverter();
              StringBuffer buf = c.convert(value, valueContext, context);
              if (buf != null) doc.setEntityTag(buf.toString());
            }
          }
        } else {
          process(source, objectContext, context, conventions, dest, accessor);
        }
      }      
      finish(
        source, 
        objectContext, 
        context, 
        dest);
      return dest;      
  }
    
  protected Object eval(AccessibleObject accessor, Object parent) {
    try {
      if (accessor instanceof Field) 
        return ((Field)accessor).get(parent);
      else if (accessor instanceof Method) 
        return ((Method)accessor).invoke(parent, new Object[0]);
      else return null;
    } catch (Throwable t) {
      throw new ConversionException(t);
    }
  }
  
  protected boolean hasAnnotation(
    AnnotatedElement item, 
    Class<? extends Annotation> annotation) {
      return item.isAnnotationPresent(annotation);
  }
  
  protected Object[] toArray(Object value) {
    if (value == null) return new Object[0];
    if (value.getClass().isArray()) {
      return (Object[])value;
    } else if (value instanceof Collection) { 
      return ((Collection)value).toArray();
    } else if (value instanceof Map) {
      return ((Map)value).values().toArray();
    } else if (value instanceof Dictionary) {
      List<Object> list = new ArrayList<Object>();
      Enumeration e = ((Dictionary)value).elements();
      while(e.hasMoreElements()) list.add(e.nextElement());
      return list.toArray();
    } else if (value instanceof Iterator) { 
      List<Object> list = new ArrayList<Object>();
      Iterator i = (Iterator) value;
      while(i.hasNext()) list.add(i.next());
      return list.toArray();
    } else if (value instanceof Enumeration) {
      List<Object> list = new ArrayList<Object>();
      Enumeration e = (Enumeration) value;
      while(e.hasMoreElements()) list.add(e.nextElement());
      return list.toArray();
    } else if (value instanceof Iterable) {
      List<Object> list = new ArrayList<Object>();
      Iterable v = (Iterable) value;
      Iterator i = v.iterator();
      while(i.hasNext()) list.add(i.next());
      return list.toArray();
    } else {
      return new Object[] {value};
    }
  }
}
