/*
 * 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.rya.indexing.pcj.storage.accumulo;

import org.eclipse.rdf4j.query.Binding;
import org.eclipse.rdf4j.query.BindingSet;

import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
import edu.umd.cs.findbugs.annotations.NonNull;

/**
 * Converts {@link BindingSet}s into other representations. This library is
 * intended to convert between BindingSet and whatever format it is being
 * stored as. These formats are often optimized for query evaluation.
 *
 * @param <T> Defines the type of model {@link BindingSet}s will be converted into/from.
 */
@DefaultAnnotation(NonNull.class)
public interface BindingSetConverter<T> {

   /**
    * Converts a {@link BindingSet} into the target model. The target model
    * may not include every {@link Binding} that was in the original BindingSet,
    * it may not include the binding names, and it may order the binding values.
    * All of this information is specified using a {@link VariableOrder}.
    * </p>
    * Because the resulting model may not include the binding names from the
    * original object, you must hold onto that information if you want to
    * convert the resulting model back into a BindingSet later. Because the
    * resulting model may only contain a subset of the original BindingSet's
    * bindings, some information may be lost, so you may not be able to convert
    * the target model back into the original BindingSet.
    *
    * @param bindingSet - The BindingSet that will be converted. (not null)
    * @param varOrder - Which bindings and in what order they will appear in the
    *   resulting model. (not null)
    * @return The BindingSet formatted as the target model.
    * @throws BindingSetConversionException The BindingSet was unable to be
    *   converted into the target model. This will happen if one of the values
    *   could not be converted into the target model.
    */
   public T convert(BindingSet bindingSet, VariableOrder varOrder) throws BindingSetConversionException;

   /**
    * Converts the target model representation of a {@link BindingSet} as is
    * created by {@link #convert(BindingSet, VariableOrder)} back into a
    * BindingSet.
    * </p>
    * You must provide the Binding names and the order they were written to
    * by using a {@link VariableOrder}.
    * </p>
    * If there is no value for one of the variable order names, then that binding
    * will be missing from the resulting BindingSet.
    *
    * @param bindingSet - The BindingSet formatted as the target model that will
    *   be converted. (not null)
    * @param varOrder - The VariableOrder that was used to create the target model. (not null)
    * @return The {@link BindingSet} representation of the target model.
    * @throws BindingSetConversionException The target model was unable to be
    *   converted back into a BindingSet.
    */
   public BindingSet convert(T bindingSet, VariableOrder varOrder) throws BindingSetConversionException;

   /**
    * One of the conversion methods of {@link BindingSetConverter} was unable to
    * to convert the {@link BindingSet} to/from the converted model.
    */
   public static class BindingSetConversionException extends Exception {
       private static final long serialVersionUID = 1L;

       /**
        * Constructs an instance of {@link BindingSetConversionException}.
        *
        * @param message - Describes why this exception was thrown.
        */
       public BindingSetConversionException(final String message) {
           super(message);
       }

       /**
        * BindingSetConversionException
        *
        * @param message - Describes why this exception was thrown.
        * @param cause - The exception that caused this one to be thrown.
        */
       public BindingSetConversionException(final String message, final Throwable cause) {
           super(message, cause);
       }
   }
}