require 'base64'
require 'fileutils'
require_relative '../dataset_utils'
require_relative '../filelogger'

module Embulk
  module Output

    class Fifoutput < OutputPlugin
      Plugin.register_output("fif", self)

      def self.transaction(config, schema, count, &control)
	@logger = LogManager.instance()
	task = { "output_path" => config.param("output_path", :string,  :default => nil) }
	if File.directory?(task['output_path'])
	else
      	  @logger.error("Output directory not found.", print=TRUE)
	  @logger.abortExecution()
	end
	task_reports = yield(task)
	next_config_diff = {}
	return next_config_diff
      end

      def init
	@output_path = task["output_path"]
	@logger = LogManager.instance()
      end

      def close
      end

      def add(page)
	begin
	  page.each do |record|
	    reference = record[0]
	    @dataset_utils = DatasetUtils.new("")
	    data_set_directory = @dataset_utils.appendSlashTo(@output_path)
	    file_path = @dataset_utils.referenceToPath(reference, data_set_directory, record[2])
	    write_mode = 'ab'
	    if record[3] == DatasetUtils::DELETE
	      @logger.info("Deleting '#{file_path}'", print=TRUE)
	      File.delete(file_path) if File.exist?(file_path)
	    elsif record[4] == TRUE.to_s # if renamed
	      new_file_path = @dataset_utils.referenceToPath(record[1], data_set_directory, record[2])
	      @logger.info("Renaming '#{file_path}' to '#{new_file_path}'", print=TRUE)
	      unless File.directory?(File.dirname(new_file_path))
		FileUtils.mkdir_p(File.dirname(new_file_path))
	      end
	      FileUtils.mv(file_path, new_file_path) if File.exist?(file_path)
	    else
	      data_chunk = Base64.decode64(record[1])
	      if record[3] == TRUE.to_s
		write_mode = 'w'
	      end
	      dirname = File.dirname(file_path)
	      unless File.directory?(dirname)
		FileUtils.mkdir_p(dirname)
	      end
	      File.open(file_path, write_mode) { |file| file.write(data_chunk) }
	    end
	  end
	rescue Exception => e  
	  @logger.error("An error occurred while procesing file.", print=TRUE)
	  @logger.error(e.backtrace)
	  raise e
	end
      end

      def finish
      end

      def abort
      end

      def commit
	task_report = {}
	return task_report
      end

    end
  end
end
