/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  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.
 */
package org.apache.beam.runners.dataflow.util;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableList;

/** A utility for manipulating well-known cloud types. */
@SuppressWarnings("ImmutableEnumChecker")
enum CloudKnownType {
  TEXT("http://schema.org/Text", String.class) {
    @Override
    public <T> T parse(Object value, Class<T> clazz) {
      return clazz.cast(value);
    }
  },
  BOOLEAN("http://schema.org/Boolean", Boolean.class) {
    @Override
    public <T> T parse(Object value, Class<T> clazz) {
      return clazz.cast(value);
    }
  },
  INTEGER("http://schema.org/Integer", Long.class, Integer.class) {
    @Override
    public <T> T parse(Object value, Class<T> clazz) {
      Object result = null;
      if (value.getClass() == clazz) {
        result = value;
      } else if (clazz == Long.class) {
        if (value instanceof Integer) {
          result = ((Integer) value).longValue();
        } else if (value instanceof String) {
          result = Long.valueOf((String) value);
        }
      } else if (clazz == Integer.class) {
        if (value instanceof Long) {
          result = ((Long) value).intValue();
        } else if (value instanceof String) {
          result = Integer.valueOf((String) value);
        }
      }
      return clazz.cast(result);
    }
  },
  FLOAT("http://schema.org/Float", Double.class, Float.class) {
    @Override
    public <T> T parse(Object value, Class<T> clazz) {
      Object result = null;
      if (value.getClass() == clazz) {
        result = value;
      } else if (clazz == Double.class) {
        if (value instanceof Float) {
          result = ((Float) value).doubleValue();
        } else if (value instanceof String) {
          result = Double.valueOf((String) value);
        }
      } else if (clazz == Float.class) {
        if (value instanceof Double) {
          result = ((Double) value).floatValue();
        } else if (value instanceof String) {
          result = Float.valueOf((String) value);
        }
      }
      return clazz.cast(result);
    }
  };

  private final String uri;
  private final ImmutableList<Class<?>> classes;

  CloudKnownType(String uri, Class<?>... classes) {
    this.uri = uri;
    this.classes = ImmutableList.copyOf(classes);
  }

  public String getUri() {
    return uri;
  }

  public abstract <T> T parse(Object value, Class<T> clazz);

  public Class<?> defaultClass() {
    return classes.get(0);
  }

  private static final Map<String, CloudKnownType> typesByUri =
      Collections.unmodifiableMap(buildTypesByUri());

  private static Map<String, CloudKnownType> buildTypesByUri() {
    Map<String, CloudKnownType> result = new HashMap<>();
    for (CloudKnownType ty : CloudKnownType.values()) {
      result.put(ty.getUri(), ty);
    }
    return result;
  }

  @Nullable
  public static CloudKnownType forUri(@Nullable String uri) {
    if (uri == null) {
      return null;
    }
    return typesByUri.get(uri);
  }

  private static final Map<Class<?>, CloudKnownType> typesByClass =
      Collections.unmodifiableMap(buildTypesByClass());

  private static Map<Class<?>, CloudKnownType> buildTypesByClass() {
    Map<Class<?>, CloudKnownType> result = new HashMap<>();
    for (CloudKnownType ty : CloudKnownType.values()) {
      for (Class<?> clazz : ty.classes) {
        result.put(clazz, ty);
      }
    }
    return result;
  }

  @Nullable
  public static CloudKnownType forClass(Class<?> clazz) {
    return typesByClass.get(clazz);
  }
}
