require 'aigu/version'

require 'optparse'
require 'fileutils'
require 'json'
require 'yaml'

require 'aigu/extensions/hash'
require 'aigu/cli'

module Aigu
  PUBLIC_COMMANDS = %w(import export)

  def self.import(input_file: nil, output_directory: nil)
    puts "Generating YAML files in `#{output_directory}` based on Accent-generated `#{input_file}` file"
    puts '---'
    json = File.read(input_file)
    object = JSON.parse(json)
    blob = Hash.recursive

    object.each_pair do |key, value|
      filename, flat_key = key.split('|')

      parts = flat_key.split('.')
      hash = blob[filename]

      parts.each_with_index do |part, index|
        if index + 1 < parts.length
          hash = hash[part]
        else
          hash[part] = value
        end
      end
    end

    blob.each_pair do |file_name, hash|
      file_path = File.join(output_directory, "#{file_name}.yml")
      puts "Generating #{file_path}"
      FileUtils.mkdir_p(File.dirname(file_path))

      File.open(file_path, 'w+') do |file|
        file << hash.to_yaml(line_width: 100_000_000)
      end
    end

    puts '---'
    puts 'Done'
  end

  def self.export(output_file: nil, input_directory: nil)
    puts "Generating Accent JSON file `#{output_file}` based on YAML localization files in `#{input_directory}` directory"
    puts '---'

    output = {}

    Dir[File.join(input_directory, '**', '*.yml')].each do |file|
      content = YAML.load_file(file)
      base_key = file.gsub(input_directory, '').gsub(/^\/*/, '').gsub(/\.yml$/, '|')

      output.merge! flattenize_hash(content, base_key)
    end

    file_path = output_file
    puts "Generating #{file_path}"
    FileUtils.mkdir_p(File.dirname(file_path))

    File.open(file_path, 'w+') do |file|
      file << output.to_json
    end

    puts '---'
    puts 'Done'
  end

  def self.flattenize_hash(hash, base_key = '')
    if hash.is_a?(Hash)
      hash.reduce({}) do |memo, (key, value)|
        new_base_key = [base_key, key].join('.').sub('|.', '|')
        memo.merge! flattenize_hash(value, new_base_key)
      end
    else
      { base_key => hash }
    end
  end
end