require 'find'
require 'yaml'
require_relative 'string_helper'
require 'axlsx'

module QAHelpers
  class FeaturesParser
    attr_reader :cucumber_pwd
    LABEL_LINE_PATTERN = /a Workstation (.*_.*) user/
    USER_CONF_FILE_PATH = '/features/yml/user_config.yml'.freeze
    XLS_HEADER = ['LABEL', 'ID', 'VEND CONTACT ID', 'FEATURES'].freeze
    XLS_FILE_NAME = 'test_matrix.xlsx'.freeze

    def initialize(cucumber_pwd)
      @cucumber_pwd = cucumber_pwd
    end

    def users_to_features_stdout
      results = users_to_features.sort_by { |_key, value| value[:features].count }.reverse
      results.each do |label, details|
        features = details[:features]
        puts "#{label} is used in #{features.count} scenarios".blue
        puts "  #{features.join("\n  ")}".green
      end
      scenario_count = users_to_features.values.map { |x| x[:features] }.flatten.count
      puts "=== #{results.count} labels found in #{scenario_count} scenarios ===".blue
      scenario_count
    end

    def users_to_features_xls
      xls = Axlsx::Package.new
      wb = xls.workbook
      worksheet = wb.add_worksheet(name: 'Test Matrix')
      styles = wb.styles
      wrap = styles.add_style alignment: {wrap_text: true}
      header = styles.add_style bg_color: 'F0F0F0', fg_color: '00', b: true
      worksheet.add_row(XLS_HEADER, style: header)
      results = users_to_features.sort_by { |_key, value| value[:features].count }.reverse
      results.each do |label, details|
        row = [
          label,
          details[:user_info][:id],
          details[:user_info][:vend_contact_id],
          details[:features].join("\r")
        ]
        worksheet.add_row(row, style: wrap)
      end
      xls.serialize XLS_FILE_NAME
      "#{File.join(Dir.pwd, XLS_FILE_NAME)} file was successfully created.".green
    end

    private

    def users_to_features
      result = {}
      all_feature_files.each do |feature_file|
        feature_labels = File.read(feature_file).scan(LABEL_LINE_PATTERN).flatten
        next if feature_labels.empty?
        feature_labels.each do |label|
          result[label] ||= {}
          result[label][:user_info] ||= label_details(label)
          result[label][:features] ||= []
          result[label][:features] << feature_file.gsub(cucumber_pwd, '')
        end
      end
      result
    end

    def label_details(label)
      user_config[:workstation][label.to_sym]
    end

    def user_config
      @user_config ||= YAML.load_file(File.join(cucumber_pwd, USER_CONF_FILE_PATH))
    end

    def all_feature_files
      path_to_features = File.join(cucumber_pwd, '/features')
      feature_file_paths = []
      Find.find(path_to_features) do |path|
        feature_file_paths << path if path =~ /.*\.feature$/
      end
      feature_file_paths
    end
  end
end
