// Copyright 2009 Google 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.google.gwtorm.protobuf;

import com.google.gwtorm.client.Column;
import com.google.gwtorm.server.GeneratedClassLoader;
import com.google.gwtorm.server.OrmException;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;

/** Creates {@link ProtobufCodec} implementations on demand. */
public final class CodecFactory {
  private static final Map<Class<?>, String> encoders =
      Collections.synchronizedMap(new WeakHashMap<Class<?>, String>());

  /**
   * Create an implementation to encode/decode an arbitrary object.
   *
   * <p>The object must use the {@link Column} annotations to denote the fields that should be
   * encoded or decoded.
   *
   * @param <T> type of the object to be supported.
   * @param type the object type.
   * @return an encoder for this object type.
   * @throws IllegalArgumentException the object's fields aren't declared properly. This is a
   *     programming error that cannot be recovered.
   */
  public static <T> ProtobufCodec<T> encoder(Class<T> type) throws IllegalStateException {
    final GeneratedClassLoader loader = newLoader(type);
    ProtobufCodec<T> encoder = null;
    String cacheName = encoders.get(type);
    if (cacheName != null) {
      encoder = get(loader, cacheName);
    }
    if (encoder == null) {
      final CodecGen<T> gen = new CodecGen<>(loader, type);
      try {
        encoder = gen.create();
      } catch (OrmException e) {
        throw new IllegalArgumentException(
            "Class " + type.getName() + " cannot be supported on protobuf", e);
      }
      encoders.put(type, encoder.getClass().getName());
    }
    return encoder;
  }

  private static <T> GeneratedClassLoader newLoader(final Class<T> type) {
    return new GeneratedClassLoader(type.getClassLoader());
  }

  @SuppressWarnings("unchecked")
  private static <T> ProtobufCodec<T> get(ClassLoader cl, String name) {
    try {
      return (ProtobufCodec<T>) Class.forName(name, true, cl).newInstance();
    } catch (InstantiationException e) {
      return null;
    } catch (IllegalAccessException e) {
      return null;
    } catch (ClassNotFoundException e) {
      return null;
    }
  }

  private CodecFactory() {}
}
