package com.srbenoit.filter.filters;

import com.srbenoit.filter.AbstractFilter;
import com.srbenoit.filter.FilterException;
import com.srbenoit.filter.FilterInput;
import com.srbenoit.filter.FilterOutput;
import com.srbenoit.filter.FilterTreeExecutor;
import com.srbenoit.filter.Pipe;
import com.srbenoit.filter.items.ByteArrayPipeItem;
import com.srbenoit.filter.items.StringPipeItem;
import org.bouncycastle.util.encoders.Base64;

/**
 * A filter that converts a Base-64 representation of some data back into the raw byte array.
 */
public class FromBase64 extends AbstractFilter {

    /** version number for serialization */
    private static final long serialVersionUID = -374358648313375169L;

    /**
     * Constructs a new <code>FromBase64</code>.
     */
    public FromBase64() {

        super("FromBase64", FromBase64.class.getName());

        this.inputs.add(new FilterInput(StringPipeItem.class, "Base-64 encoded string"));
        this.outputs.add(new FilterOutput(ByteArrayPipeItem.class, "Recovered binary data",
                "binary"));
    }

    /**
     * Duplicates the filter including all of its settings, but returns an independent object.
     *
     * @return  the duplicated object
     */
    @Override public AbstractFilter duplicate() {

        return new FromBase64();
    }

    /**
     * Performs the filter operation.
     *
     * @param   executor  the <code>FilterTreeExecutor</code> that is executing the filter
     * @param   pipe      a pipe containing the input data items
     * @throws  FilterException  if the filter cannot complete
     */
    @Override public void filter(final FilterTreeExecutor executor, final Pipe pipe)
        throws FilterException {

        StringPipeItem in0;
        ByteArrayPipeItem out0;

        validateInputs(pipe);

        in0 = (StringPipeItem) pipe.get("Base64");

        out0 = new ByteArrayPipeItem("decoded", "Binary", pipe);
        out0.setData(Base64.decode(in0.getData()));

        pipe.add(out0);
    }
}
