using System;
using System.IO;
using Volpe.Cafe.IO.DSV;

namespace Volpe.Cafe.IO.CSV
{
    /// <summary>
    /// Provides static methods for the creation and opening of a comma-separated values (CSV) file.
    /// </summary>
    /// <remarks>
    /// The processing of CSV files (via the <see cref="CsvReader"/> and the <see cref="CsvWriter"/> classes) follows
    /// the RFC 4180 specification for the CSV file format (as outlined here: https://www.rfc-editor.org/rfc/rfc4180).
    /// In particular, the CSV classes adapt the specifics related to the treatment of the delimiter character (i.e.,
    /// comma), the escape character (i.e., the double quote <c>'"'</c>), and the various new line characters or string
    /// (CR or <c>'\r'</c>, LF or <c>'\n'</c>, CRLF or <c>"\r\n"</c>).
    /// </remarks>
    [Serializable]
    public static class CsvFile
    {
        /// <summary>
        /// Defines a character used for delimiting the columns in a CSV file.
        /// </summary>
        public const char Delimiter = ',';

        /// <summary>
        /// Opens a CSV file at the specified <paramref name="path"/> for writing. If the file exists, it will be
        /// overwritten; otherwise, a new file will be created. The specified <paramref name="headers"/> will be
        /// written to the file upon successful opening.
        /// </summary>
        /// <param name="path">The complete file path to write to.</param>
        /// <param name="headers">An array of column headers to write to the CSV file.</param>
        /// <returns>A <see cref="CsvWriter"/> instance to use for writing the CSV file.</returns>
        /// <inheritdoc cref="CsvWriter(string, string[])" path="/exception"/>
        public static CsvWriter OpenWrite(string path, string[] headers)
        {
            ThrowHelper.ThrowIfHeadersNotValid(headers);
            return new CsvWriter(path, headers);
        }

        /// <summary>
        /// Opens an existing CSV file at the specified <paramref name="path"/> for writing. If the file exists, it
        /// will be appended to; otherwise, an exception will be thrown.
        /// </summary>
        /// <param name="path">The complete file path to write to.</param>
        /// <returns>A <see cref="CsvWriter"/> instance to use for writing the CSV file.</returns>
        /// <exception cref="FileNotFoundException">The file cannot be found.</exception>
        /// <inheritdoc cref="StreamWriter(string, bool)" path="/exception"/>
        public static CsvWriter OpenAppend(string path)
        {
            ThrowHelper.ThrowIfFileNotFound(path);
            return new CsvWriter(path, null);
        }

        /// <summary>
        /// Opens a CSV file at the specified <paramref name="path"/> for reading.
        /// </summary>
        /// <param name="path">The complete file path to read.</param>
        /// <returns>A <see cref="CsvReader"/> instance to use for reading the CSV file.</returns>
        /// <inheritdoc cref="CsvReader(string)" path="/exception"/>
        public static CsvReader OpenRead(string path)
        {
            return new CsvReader(path);
        }

    }
}
