/**
 * Copyright (C) 2015 DataTorrent, Inc.
 *
 * 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 com.datatorrent.api;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;

import com.datatorrent.netlet.util.DTThrowable;
import java.util.*;

/**
 * This interface is essentially serializer/deserializer interface which works with String as
 * the serialized type. When initializing the attributes from the properties file, attribute
 * values represented as Strings are needed to be converted to POJO. This class facilitates the
 * conversion from and to String for attribute values.
 *
 * @param <T> Type of the object which can be converted to/from String.
 * @since 0.9.0
 */
public interface StringCodec<T>
{
  /**
   * Given a string representation (typically from properties file) for an object , create object from it.
   *
   * @param string Type of the POJO which is created from String representation.
   * @return POJO obtained as a result of deserialization
   */
  T fromString(String string);

  /**
   * Given a POJO, serialize it to a String object (typically to be stored in properties file).
   *
   * @param pojo The object which needs to be serialized.
   * @return Serialized representation of pojo..
   */
  String toString(T pojo);

  public class String2String implements StringCodec<String>, Serializable
  {
    @Override
    public String fromString(String string)
    {
      return string;
    }

    @Override
    public String toString(String pojo)
    {
      return pojo;
    }

    private static final long serialVersionUID = 201310141156L;
  }

  public class Integer2String implements StringCodec<Integer>, Serializable
  {
    @Override
    public Integer fromString(String string)
    {
      return Integer.valueOf(string);
    }

    @Override
    public String toString(Integer pojo)
    {
      return String.valueOf(pojo);
    }

    private static final long serialVersionUID = 201310141157L;
  }

  public class Long2String implements StringCodec<Long>, Serializable
  {
    @Override
    public Long fromString(String string)
    {
      return Long.valueOf(string);
    }

    @Override
    public String toString(Long pojo)
    {
      return String.valueOf(pojo);
    }

    private static final long serialVersionUID = 201310141158L;
  }

  public class Boolean2String implements StringCodec<Boolean>, Serializable
  {
    @Override
    public Boolean fromString(String string)
    {
      return Boolean.valueOf(string);
    }

    @Override
    public String toString(Boolean pojo)
    {
      return String.valueOf(pojo);
    }

    private static final long serialVersionUID = 201310141159L;
  }

  /**
   * The attributes which represent arbitrary objects for which the schema cannot be
   * standardized, we allow them to be represented as <ClassName>:<Constructor_String>:<Property_String> representation.
   * This allows us to instantiate the class by invoking its constructor which takes
   * <String> as argument.  If only the <ClassName> is specified, then just the class is instantiated using default
   * constructor. If colon is specified then class is instantiated using constructor with
   * string as an argument.If properties are specified then properties will be set on the object. The properties
   * are defined in property=value format separated by colon(:)
   *
   * @param <T> Type of the object which is converted to/from String
   */
  public class Object2String<T> implements StringCodec<T>, Serializable
  {
    public final String separator;
    public final String propertySeparator;

    public Object2String()
    {
      separator = ":";
      propertySeparator = "=";
    }

    public Object2String(String separator)
    {
      this.separator = separator;
      this.propertySeparator = "=";
    }

    public Object2String(String separator, String propertySeparator)
    {
      this.separator = separator;
      this.propertySeparator = propertySeparator;
    }

    @Override
    @SuppressWarnings({"UseSpecificCatch", "BroadCatchBlock", "TooBroadCatch"})
    public T fromString(String string)
    {
      String[] parts = string.split(separator);

      try {
        @SuppressWarnings("unchecked")
        Class<? extends T> clazz = (Class<? extends T>) Thread.currentThread().getContextClassLoader().loadClass(parts[0]);
        if (parts.length == 1) {
          return clazz.newInstance();
        }

        //String[] properties = parts[1].split(separator, 2);
        if (parts.length == 2) {
          return clazz.getConstructor(String.class).newInstance(parts[1]);
        }
        else {
          T object = clazz.getConstructor(String.class).newInstance(parts[1]);
          HashMap<String, String> hashMap = new HashMap<String, String>();
          for (int i = 2; i < parts.length; i++) {
            String[] keyValPair = parts[i].split(propertySeparator, 2);
            hashMap.put(keyValPair[0], keyValPair[1]);
          }
          BeanUtils.populate(object, hashMap);
          return object;
        }
      }
      catch (Throwable cause) {
        DTThrowable.rethrow(cause);
      }

      return null;
    }

    @Override
    public String toString(T pojo)
    {
      String arg = pojo.toString();
      if (arg == null) {
        return pojo.getClass().getCanonicalName();
      }

      return pojo.getClass().getCanonicalName() + separator + arg;
    }

    private static final long serialVersionUID = 201311141853L;
  }

  public class Map2String<K, V> implements StringCodec<Map<K, V>>, Serializable
  {
    private final StringCodec<K> keyCodec;
    private final StringCodec<V> valueCodec;
    private final String separator;
    private final String equal;

    public Map2String(String separator, String equal, StringCodec<K> keyCodec, StringCodec<V> valueCodec)
    {
      this.equal = equal;
      this.separator = separator;
      this.keyCodec = keyCodec;
      this.valueCodec = valueCodec;
    }

    @Override
    public Map<K, V> fromString(String string)
    {
      if (string == null) {
        return null;
      }

      if (string.isEmpty()) {
        return new HashMap<K, V>();
      }

      String[] parts = string.split(separator);
      HashMap<K, V> map = new HashMap<K, V>();
      for (String part : parts) {
        String[] kvpair = part.split(equal, 2);
        map.put(keyCodec.fromString(kvpair[0]), valueCodec.fromString(kvpair[1]));
      }

      return map;
    }

    @Override
    public String toString(Map<K, V> map)
    {
      if (map == null) {
        return null;
      }

      if (map.isEmpty()) {
        return "";
      }
      String[] parts = new String[map.size()];
      int i = 0;
      for (Map.Entry<K, V> entry : map.entrySet()) {
        parts[i++] = keyCodec.toString(entry.getKey()) + equal + valueCodec.toString(entry.getValue());
      }
      return StringUtils.join(parts, separator);
    }

    private static final long serialVersionUID = 201402272053L;
  }

  public class Collection2String<T> implements StringCodec<Collection<T>>, Serializable
  {
    private final String separator;
    private final StringCodec<T> codec;

    public Collection2String(String separator, StringCodec<T> codec)
    {
      this.separator = separator;
      this.codec = codec;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Collection<T> fromString(String string)
    {
      if (string == null) {
        return null;
      }

      if (string.isEmpty()) {
        return Collections.EMPTY_LIST;
      }

      String[] parts = string.split(separator);
      ArrayList<T> arrayList = new ArrayList<T>(parts.length);
      for (String part : parts) {
        arrayList.add(codec.fromString(part));
      }

      return arrayList;
    }

    @Override
    public String toString(Collection<T> pojo)
    {
      if (pojo == null) {
        return null;
      }

      if (pojo.isEmpty()) {
        return "";
      }

      String[] parts = new String[pojo.size()];

      int i = 0;
      for (T o : pojo) {
        parts[i++] = codec.toString(o);
      }

      return StringUtils.join(parts, separator);
    }

    private static final long serialVersionUID = 201401091806L;
  }

  public class Enum2String<T extends Enum<T>> implements StringCodec<T>, Serializable
  {
    private final Class<T> clazz;

    public Enum2String(Class<T> clazz)
    {
      this.clazz = clazz;
    }

    @Override
    public T fromString(String string)
    {
      return Enum.valueOf(clazz, string);
    }

    @Override
    public String toString(T pojo)
    {
      return pojo.name();
    }

    private static final long serialVersionUID = 201310181757L;
  }

  public class Class2String<T> implements StringCodec<Class<? extends T>>, Serializable
  {
    @Override
    @SuppressWarnings({"BroadCatchBlock", "TooBroadCatch"})
    public Class<? extends T> fromString(String string)
    {
      try {
        @SuppressWarnings({"rawtypes", "unchecked"})
        Class<? extends T> clazz = (Class)Thread.currentThread().getContextClassLoader().loadClass(string);
        return clazz;
      }
      catch (Throwable cause) {
        DTThrowable.rethrow(cause);
      }

      return null;
    }

    @Override
    public String toString(Class<? extends T> clazz)
    {
      return clazz.getCanonicalName();
    }

    private static final long serialVersionUID = 201312082053L;
  }

}
