/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * license agreements; and to You under the Apache License, version 2.0:
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * This file is part of the Apache Pekko project, which was derived from Akka.
 */

/*
 * Copyright (C) 2014 - 2016 Softwaremill <https://softwaremill.com>
 * Copyright (C) 2016 - 2020 Lightbend Inc. <https://www.lightbend.com>
 */

package org.apache.pekko.kafka.benchmarks

import java.nio.charset.{ Charset, StandardCharsets }
import org.apache.pekko
import pekko.NotUsed
import pekko.stream.scaladsl.{ Flow, Source }
import pekko.util.ByteString

import scala.collection.immutable

/**
 * Provides CSV formatting flows that convert a sequence of String into their CSV representation
 * in [[pekko.util.ByteString]].
 */
private[benchmarks] object CsvFormatting {

  /**
   * Create a Flow for converting iterables to ByteString.
   *
   * @param endOfLine     Line ending (default CR, LF)
   * @param quotingStyle  Quote all fields, or only fields requiring quotes (default)
   * @param charset       Character set, defaults to UTF-8
   * @param byteOrderMark Certain CSV readers (namely Microsoft Excel) require a Byte Order mark, defaults to None
   */
  def format[T <: immutable.Iterable[String]](
      delimiter: Char = ',',
      quoteChar: Char = '"',
      escapeChar: Char = '\\',
      endOfLine: String = "\r\n",
      quotingStyle: CsvQuotingStyle = CsvQuotingStyle.Required,
      charset: Charset = StandardCharsets.UTF_8,
      byteOrderMark: Option[ByteString] = None): Flow[T, ByteString, NotUsed] = {
    val formatter =
      new CsvFormatter(delimiter, quoteChar, escapeChar, endOfLine, quotingStyle, charset)
    byteOrderMark.fold {
      Flow[T].map(formatter.toCsv).named("CsvFormatting")
    } { bom =>
      Flow[T].map(formatter.toCsv).named("CsvFormatting").prepend(Source.single(bom))
    }

  }
}
