#!/usr/bin/env ruby
# Copyright (c) 2017-2022 Yegor Bugayenko
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the 'Software'), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

STDOUT.sync = true

require 'slop'
require 'nokogiri'
require 'set'
require_relative '../lib/xcop/cli'
require_relative '../lib/xcop/version'

if Gem::Version.new(Nokogiri::VERSION) < Gem::Version.new('1.8')
  puts "Nokogiri version #{Nokogiri::VERSION} is too old, 1.8+ is required"
end

def config(path)
  f = File.expand_path(path)
  args = []
  args += File.readlines(f).map(&:strip) if File.exist?(f)
  args
end

args = config('~/.xcop') + config('.xcop') + ARGV

opts = Slop.parse(args, strict: true, help: true) do |o|
  o.banner = "Usage (#{Xcop::VERSION}): xcop [options] [files...]"
  o.bool '-h', '--help', 'Show these instructions'
  o.bool '-q', '--quiet', 'Don\'t print anything if there are no errors'
  o.bool '--version', 'Show current version'
  o.bool '--fix', 'Fix all files instead of reporting their problems'
  o.bool '--nocolor', 'Suppress colored output'
  o.string '--license', 'File name of the boilerplate head license'
  o.array '--include', 'Glob pattern(s) to include'
  o.array '--exclude', 'Glob pattern(s) to exclude'
end

if opts.help?
  puts opts
  exit
end

if opts.version?
  puts Xcop::VERSION
  exit
end

Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

license = ''
if opts.license?
  unless File.exist?(opts[:license])
    puts "License file is absent: #{opts[:license]}"
    exit -1
  end
  license = File.read(opts[:license])
end

files = Set.new

if opts[:include]
  opts[:include].each do |glob|
    files += Dir.glob(glob).map { |f| File.expand_path(f) }
  end
end

files += opts.arguments.map { |f| File.expand_path(f) }

if opts[:exclude]
  opts[:exclude].each do |glob|
    files -= Dir.glob(glob).map { |f| File.expand_path(f) }
  end
end

if opts.fix?
  Xcop::CLI.new(files, license).fix do |f|
    puts "#{f} fixed" unless opts.quiet?
  end
else
  begin
    Xcop::CLI.new(files, license, nocolor: opts.nocolor?).run do |f|
      puts "#{f} looks good" unless opts.quiet?
    end
  rescue StandardError => e
    puts e.message
    exit -1
  end
end
