package eu.dnetlib.data.transform;

import java.util.Arrays;
import java.util.Set;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;

import eu.dnetlib.data.mapreduce.util.OafDecoder;
import eu.dnetlib.data.proto.FieldTypeProtos.StructuredProperty;
import eu.dnetlib.data.proto.KindProtos.Kind;
import eu.dnetlib.data.proto.OafProtos.Oaf;
import eu.dnetlib.data.proto.TypeProtos.Type;

public class OafUtils {

	public static Set<String> entities() {
		return Sets.newHashSet(Iterables.transform(Lists.newArrayList(Type.values()), new Function<Type, String>() {

			@Override
			public String apply(final Type t) {
				return t.toString();
			}
		}));
	}

	public static Predicate<Oaf> relationFilter() {
		return new Predicate<Oaf>() {

			@Override
			public boolean apply(final Oaf oaf) {
				return oaf.getKind().equals(Kind.relation);
			}
		};
	}

	public static Predicate<Oaf> entityFilter() {
		return new Predicate<Oaf>() {

			@Override
			public boolean apply(final Oaf oaf) {
				return oaf.getKind().equals(Kind.entity);
			}
		};
	}

	public static Function<OafDecoder, String> idDecoder() {
		return new Function<OafDecoder, String>() {

			@Override
			public String apply(final OafDecoder input) {
				return input.getEntityId();
			}
		};
	}

	public static Predicate<StructuredProperty> mainTitleFilter() {
		return new Predicate<StructuredProperty>() {

			@Override
			public boolean apply(final StructuredProperty sp) {
				return (sp.getQualifier() != null) && sp.getQualifier().getClassname().equals("main title");
			}
		};
	}

	public static Set<String> getFieldNames(final Descriptor d, final Integer... tag) {
		return Sets.newHashSet(Iterables.transform(Arrays.asList(tag), new Function<Integer, String>() {

			@Override
			public String apply(final Integer i) {
				final FieldDescriptor fd = d.findFieldByNumber(i);
				if (fd == null) throw new IllegalArgumentException("undefined tag: " + i + " for type: " + d.getFullName());
				return fd.getName();
			}
		}));
	}

}
