package eu.dnetlib.data.mapreduce.util;

import eu.dnetlib.data.proto.DatasourceOrganizationProtos.DatasourceOrganization;
import eu.dnetlib.data.proto.DedupRelProtos.DedupRel;
import eu.dnetlib.data.proto.OafProtos.OafRel;
import eu.dnetlib.data.proto.PersonPersonProtos.PersonPerson;
import eu.dnetlib.data.proto.PersonResultProtos.PersonResult;
import eu.dnetlib.data.proto.ProjectContactpersonProtos.ProjectContactperson;
import eu.dnetlib.data.proto.ProjectOrganizationProtos.ProjectOrganization;
import eu.dnetlib.data.proto.QualifierProtos.Qualifier;
import eu.dnetlib.data.proto.RelMetadataProtos.RelMetadata;
import eu.dnetlib.data.proto.RelTypeProtos.RelType;
import eu.dnetlib.data.proto.ResultOrganizationProtos.ResultOrganization;
import eu.dnetlib.data.proto.ResultProjectProtos.ResultProject;
import eu.dnetlib.data.proto.ResultProtos.Result;
import eu.dnetlib.data.proto.ResultResultProtos.ResultResult;
import eu.dnetlib.data.proto.SimilarRelProtos.SimilarRel;
import eu.dnetlib.data.proto.SimilarityRelProtos.SimilarityRel;
import eu.dnetlib.data.proto.StructuredPropertyProtos.StructuredProperty;

public class ProtoUtils {

	public static Qualifier.Builder getQualifier(final String classname, final String schemename) {
		return Qualifier.newBuilder().setClassid(classname).setClassname(classname).setSchemeid(schemename).setSchemename(schemename);
	}

	public static StructuredProperty.Builder getStruct(final String value, final Qualifier.Builder qualifier) {
		return StructuredProperty.newBuilder().setValue(value).setQualifier(qualifier);
	}

	public static Result.Builder result(final String title) {
		return Result.newBuilder().setMetadata(resultMetadata(title));
	}

	public static OafRel.Builder rel(final String source, final String target, final RelType relType, final boolean isChild) {
		OafRel.Builder builder = OafRel.newBuilder().setSource(source).setTarget(target).setRelType(relType).setChild(isChild);
		switch (relType) {
		case datasourceOrganization:
			builder.setDatasourceOrganization(datasourceOrganization());
			break;
		case personResult:
			builder.setPersonResult(personResult());
			break;
		case projectContactperson:
			builder.setProjectContactperson(projectContactperson());
			break;
		case projectOrganization:
			builder.setProjectOrganization(projectOrganization());
			break;
		case resultOrganization:
			builder.setResultOrganization(resultOrganization());
			break;
		case resultProject:
			builder.setResultProject(resultProject());
			break;
		case dedupRel:
			builder.setDedupRel(dedupRel());
			break;
		case personPerson:
			builder.setPersonPerson(personPerson());
			break;
		case resultResult:
			builder.setResultResult(resultResult());
			break;
		case similarRel:
			builder.setSimilarRel(similarRel());
			break;
		case similarityRel:
			builder.setSimilarityRel(similarityRel());
			break;
		default:
			throw new IllegalArgumentException("not implemented");
		}
		return builder;
	}

	private static SimilarityRel.Builder similarityRel() {
		return SimilarityRel.newBuilder();
	}

	private static SimilarRel.Builder similarRel() {
		return SimilarRel.newBuilder();
	}

	private static ResultResult.Builder resultResult() {
		return ResultResult.newBuilder().setRelMetadata(relMetadata());
	}

	private static PersonPerson.Builder personPerson() {
		return PersonPerson.newBuilder().setRelMetadata(relMetadata());
	}

	private static DedupRel.Builder dedupRel() {
		return DedupRel.newBuilder();
	}

	public static DatasourceOrganization.Builder datasourceOrganization() {
		return DatasourceOrganization.newBuilder().setRelMetadata(relMetadata());
	}

	public static PersonResult.Builder personResult() {
		return PersonResult.newBuilder().setRelMetadata(relMetadata());
	}

	public static ProjectContactperson.Builder projectContactperson() {
		return ProjectContactperson.newBuilder().setRelMetadata(relMetadata());
	}

	public static ProjectOrganization.Builder projectOrganization() {
		return ProjectOrganization.newBuilder().setRelMetadata(relMetadata());
	}

	public static ResultOrganization.Builder resultOrganization() {
		return ResultOrganization.newBuilder().setRelMetadata(relMetadata());
	}

	public static ResultProject.Builder resultProject() {
		return ResultProject.newBuilder().setRelMetadata(relMetadata());
	}

	public static RelMetadata.Builder relMetadata() {
		return RelMetadata.newBuilder().setSemantics(getQualifier("class", "scheme"));
	}

	private static Result.Metadata.Builder resultMetadata(final String title) {
		return Result.Metadata.newBuilder().addTitle(getStruct(title, getQualifier("main title", "dnet_titles")));
	}
}
