module Aigu
  class CoreImporter
    ENUM_LINE_REGEX = /^\s*(?<key>\w+)\s?\("(?<value_en>.*)",\s?"(?<value_fr>.*)"\)(?<comma>[,;]?)\s$/

    def initialize(opts = {})
      @input_file = opts[:'input-file']
      @output_directory = opts[:'output-directory']
      @locale = opts[:locale]
    end

    def process!
      puts "Updating Core Java Enum files in `#{@output_directory}` based on Accent-generated `#{@input_file}` file"
      puts '---'

      parse_json
      read_java
      @java_content = update_in_memory(@java_content, @object, @locale)
      write_java

      puts '---'
      puts 'Done'
    end

  protected

    def parse_json
      json = File.read(@input_file)
      @object = JSON.parse(json)
    end

    def read_java
      pattern = File.join(@output_directory, '**', 'CoreLocalizedStrings.java')
      @filepath = Dir[pattern].first
      puts "Processing #{@filepath}"

      @java_content = File.open(@filepath, 'rb:bom|utf-8').read
    end

    def write_java
      puts "Updating #{@filepath}"
      File.open(@filepath, 'w+:bom|utf-8') do |file|
        file << @java_content
      end
    end

    def update_in_memory(java_file_content, content, locale = '')
      in_section = false
      new_content = ''

      java_file_content.each_line do |line|
        if line.include?('/* !!LOCALIZED STRINGS!! --> */')
          in_section = true
        elsif line.include?('/* <-- !!LOCALIZED STRINGS!! */')
          in_section = false
        end

        if in_section
          line_content = build_line_inside_localized_section(line, content, locale)
        end
        new_content << (line_content || line)
      end
      new_content
    end

    def build_line_inside_localized_section(line, content, locale)
      line_content = nil
      match_data = line.match(ENUM_LINE_REGEX)

      if match_data
        key = match_data[:key]

        line_content = "    #{key}(\""
        line_content << (locale != 'fr' ? content[key] : match_data[:value_en])
        line_content << '", "'
        line_content << (locale == 'fr' ? content[key] : match_data[:value_fr])
        line_content << "\")#{match_data[:comma]}\n"
      end

      line_content
    end
  end
end