/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 */
package org.biojava.bio.program.fastq;

/**
 * FASTQ formatted sequence.
 *
 * @since 1.7.1
 */
public final class Fastq
{
    /** Description of this FASTQ formatted sequence. */
    private final String description;

    /** Sequence for this FASTQ formatted sequence. */
    private final String sequence;

    /** Quality scores for this FASTQ formatted sequence. */
    private final String quality;

    /** FASTQ sequence format variant for this FASTQ formatted sequence. */
    private final FastqVariant variant;


    /**
     * Create a new FASTQ formatted sequence from the specified description, sequence, quality scores,
     * and sequence format variant.
     *
     * @param description description of this FASTQ formatted sequence, must not be null
     * @param sequence sequence for this FASTQ formatted sequence, must not be null
     * @param quality quality scores for this FASTQ formatted sequence, must not be null
     * @param variant FASTQ sequence format variant for this FASTQ formatted sequence, must not be null
     */
    Fastq(final String description,
          final String sequence,
          final String quality,
          final FastqVariant variant)
    {
        if (description == null)
        {
            throw new IllegalArgumentException("description must not be null");
        }
        if (sequence == null)
        {
            throw new IllegalArgumentException("sequence must not be null");
        }
        if (quality == null)
        {
            throw new IllegalArgumentException("quality must not be null");
        }
        if (variant == null)
        {
            throw new IllegalArgumentException("variant must not be null");
        }
        this.description = description;
        this.sequence = sequence;
        this.quality = quality;
        this.variant = variant;
    }


    /**
     * Return the description of this FASTQ formatted sequence.
     * The description will not be null.
     *
     * @return the description of this FASTQ formatted sequence
     */
    public String getDescription()
    {
        return description;
    }

    /**
     * Return the sequence for this FASTQ formatted sequence.
     * The sequence will not be null.
     *
     * @return the sequence for this FASTQ formatted sequence
     */
    public String getSequence()
    {
        return sequence;
    }

    /**
     * Return the quality scores for this FASTQ formatted sequence.
     * The quality scores will not be null.
     *
     * @return the quality scores for this FASTQ formatted sequence
     */
    public String getQuality()
    {
        return quality;
    }

    /**
     * Return the FASTQ sequence format variant for this FASTQ formatted sequence.
     * The FASTQ sequence format variant will not be null.
     *
     * @return the FASTQ sequence format variant for this FASTQ formatted sequence
     */
    public FastqVariant getVariant()
    {
        return variant;
    }

    /**
     * Create and return a new FASTQ formatted sequence from this converted to the
     * specified FASTQ sequence format variant.
     *
     * @since 1.9.3
     * @param variant FASTQ sequence format variant, must not be null
     * @return a new FASTQ formatted sequence from this converted to the
     *    specified FASTQ sequence format variant
     */
    public Fastq convertTo(final FastqVariant variant)
    {
        return FastqTools.convert(this, variant);
    }

    /**
     * Create and return a new FastqBuilder.
     * The FastqBuilder will not be null.
     *
     * @return a new FastqBuilder
     */
    public static final FastqBuilder builder()
    {
        return new FastqBuilder();
    }

    /**
     * Create and return a new FastqBuilder configured from the
     * specified FASTQ formatted sequence.
     * The FastqBuilder will not be null.
     *
     * @since 1.9.5
     * @param fastq FASTQ formatted sequence, must not be null
     * @return a new FastqBuilder configured from the specifed FASTQ
     *    formatted sequence
     */
    public static final FastqBuilder builder(final Fastq fastq)
    {
        return new FastqBuilder(fastq);
    }
}
