#!/usr/bin/ruby
# MPW is a software to crypt and manage your passwords
# Copyright (C) 2016  Adrien Waksberg <mpw@yae.im>
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

$: << File.expand_path('../../lib', __FILE__)

require 'optparse'
require 'locale'
require 'set'
require 'i18n'
require 'mpw/mpw'
require 'mpw/config'
require 'mpw/cli'

# --------------------------------------------------------- #
# Set local
# --------------------------------------------------------- #

lang = Locale::Tag.parse(ENV['LANG']).to_simple.to_s[0..1]

if defined?(I18n.enforce_available_locales)
	I18n.enforce_available_locales = true
end

I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
I18n.load_path      = Dir["#{File.expand_path('../../i18n', __FILE__)}/*.yml"]
I18n.default_locale = :en
I18n.locale         = lang.to_sym

# --------------------------------------------------------- #
# Options
# --------------------------------------------------------- #

options_password    = {}
options             = {}
options[:force]     = false
options[:otp]       = false
options[:sync]      = true
options[:clipboard] = true
options[:group]     = nil
options[:config]    = nil
options[:wallet]    = nil

OptionParser.new do |opts|
	opts.banner = "#{I18n.t('option.usage')}: mpw [options]"

	opts.on('-a', '--add', I18n.t('option.add')) do
		options[:add] = true
	end

	opts.on('-A', '--show-all', I18n.t('option.show_all')) do
		options[:type] = nil
		options[:show] = ''
	end

	opts.on('-c', '--config CONFIG', I18n.t('option.config')) do |config|
		options[:config] = config
	end

	opts.on('-C', '--no-clipboard', I18n.t('option.clipboard')) do
		options[:clipboard] = false
	end

	opts.on('-e', '--export', I18n.t('option.export')) do
		options[:export] = true
	end

	opts.on('-f', '--file FILE', I18n.t('option.file')) do |file|
		options[:file] = file
	end

	opts.on('-F', '--force', I18n.t('option.force')) do
		options[:force] = true
	end

	opts.on('-g', '--group GROUP', I18n.t('option.group')) do |group|
		options[:group] = group
	end

	opts.on('-G', '--generate-password [LENGTH]', I18n.t('option.generate_password')) do |length|
		options_password[:length] = length
	end

	opts.on('-h', '--help', I18n.t('option.help')) do
		puts opts
		exit 0
	end

	opts.on('-I', '--import', I18n.t('option.import')) do
		options[:import] = true
	end

	opts.on('-k', '--key KEY', I18n.t('option.key')) do |key|
		options[:key] = key
	end

	opts.on('-n', '--numeric', I18n.t('option.numeric')) do
		options_password[:numeric] = true
	end

	opts.on('-N', '--no-sync', I18n.t('option.no_sync')) do
		options[:sync] = false
	end

	opts.on('-O', '--otp', I18n.t('option.otp')) do
		options[:otp] = true
	end

	opts.on('-s', '--show [SEARCH]', I18n.t('option.show')) do |search|
		search.nil? ? (options[:show]  = '')  : (options[:show] = search)
	end

	opts.on('-S', '--setup', I18n.t('option.setup')) do
		options[:setup] = true
	end

	opts.on('-w', '--wallet WALLET', I18n.t('option.wallet')) do |wallet|
		options[:wallet] = wallet
	end

	opts.on('-W', '--setup-wallet', I18n.t('option.setup_wallet')) do
		options[:setup_wallet] = true
	end

	opts.on('-x', '--special-chars', I18n.t('option.special_chars')) do
		options_password[:special] = true
	end

	opts.on('-y', '--alpha', I18n.t('option.alpha')) do
		options_password[:alpha] = true
	end
end.parse!

# --------------------------------------------------------- #
# Main
# --------------------------------------------------------- #

# Generate password
if not options_password.empty?
	puts MPW::MPW::password(options_password)
	exit 0
end

begin
	config = MPW::Config.new(options[:config])
	cli    = MPW::Cli.new(config, options[:clipboard], options[:sync], options[:otp])
		
	# Setup a new config 
	if not options[:setup].nil?
		cli.setup(lang)
		exit 0
	end

	cli.setup(lang)   if not config.is_valid?
	cli.setup_gpg_key if not config.check_gpg_key?
	
	cli.get_wallet(options[:wallet])
	cli.decrypt
	
	# Display the item's informations
	if not options[:show].nil?
		opts = {search:    options[:show],
		        group:     options[:group],
		       }
	
		cli.display(opts)
	
	# Add a new item
	elsif not options[:add].nil? and options[:key].nil?
		cli.add
	
	# Add a new public key in wallet
	elsif not options[:add].nil? and not options[:key].nil?
		cli.add_key(options[:key], options[:file])
	
	# Delete a public key in wallet
	elsif not options[:delete].nil? and not options[:key].nil?
		cli.delete_key(options[:key])
	
	# Export
	elsif not options[:export].nil? and not options[:file].nil?
		cli.export(options[:file])
	
	# Import
	elsif not options[:import].nil? and not options[:file].nil?
		cli.import(options[:file])
	
	# Setup wallet config
	elsif not options[:setup_wallet].nil?
		cli.setup_wallet_config
	
	end
	
	cli = nil
	
	exit 0

rescue SystemExit, Interrupt
	exit 3
end