# frozen_string_literal: true

module JekyllImport
  module Importers
    class CSV < Importer
      def self.require_deps
        JekyllImport.require_with_fallback(%w(
          csv
          fileutils
          yaml
        ))
      end

      def self.specify_options(c)
        c.option "file",            "--file NAME",       "The CSV file to import. (default: 'posts.csv')"
        c.option "no-front-matter", "--no-front-matter", "Do not add the default front matter to the post body. (default: false)"
      end

      # Reads a csv with title, permalink, body, published_at, and filter.
      # It creates a post file for each row in the csv
      def self.process(options)
        file = options.fetch("file", "posts.csv")

        FileUtils.mkdir_p "_posts"
        posts = 0
        abort "Cannot find the file '#{file}'. Aborting." unless File.file?(file)

        ::CSV.foreach(file) do |row|
          next if row[0] == "title" # header

          posts += 1
          write_post(CSVPost.new(row), options)
        end
        Jekyll.logger.info "Created #{posts} posts!"
      end

      class CSVPost
        attr_reader :title, :permalink, :body, :markup

        MissingDataError = Class.new(RuntimeError)

        # Creates a CSVPost
        #
        # row - Array of data, length of 4 or 5 with the columns:
        #
        #   1. title
        #   2. permalink
        #   3. body
        #   4. published_at
        #   5. markup (markdown, textile)
        def initialize(row)
          @title = row[0]        || missing_data("Post title not present in first column.")
          @permalink = row[1]    || missing_data("Post permalink not present in second column.")
          @body = row[2]         || missing_data("Post body not present in third column.")
          @published_at = row[3] || missing_data("Post publish date not present in fourth column.")
          @markup = row[4]       || "markdown"
        end

        def published_at
          if @published_at && !@published_at.is_a?(DateTime)
            @published_at = DateTime.parse(@published_at)
          else
            @published_at
          end
        end

        def filename
          "#{published_at.strftime("%Y-%m-%d")}-#{File.basename(permalink, ".*")}.#{markup}"
        end

        def missing_data(message)
          raise MissingDataError, message
        end
      end

      def self.write_post(post, options = {})
        File.open(File.join("_posts", post.filename), "w") do |f|
          write_frontmatter(f, post, options)
          f.puts post.body
        end
      end

      def self.write_frontmatter(f, post, options)
        no_frontmatter = options.fetch("no-front-matter", false)
        unless no_frontmatter
          f.puts YAML.dump(
            "layout"    => "post",
            "title"     => post.title,
            "date"      => post.published_at.to_s,
            "permalink" => post.permalink
          )
          f.puts "---"
        end
      end
    end
  end
end
