#!/usr/bin/python -bO
# -*- coding:utf-8 -*-
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from __future__ import print_function, unicode_literals

import io
import logging
import sys

# import our centrally initialized portage instance
from repoman._portage import portage
portage._internal_caller = True
portage._disable_legacy_globals()


from portage import os
import portage.checksum
import portage.const
import portage.repository.config
from portage import util
from portage.output import create_color_func, nocolor
from portage.output import ConsoleStyleFile, StyleWriter
from portage.util import formatter

from repoman.actions import Actions
from repoman.argparser import parse_args
from repoman.checks.ebuilds.checks import checks_init
from repoman.qa_data import (
	format_qa_output, format_qa_output_column, qahelp,
	qawarnings, qacats)
from repoman.repos import RepoSettings
from repoman.scanner import Scanner
from repoman import utilities
from repoman.vcs.vcs import VCSSettings

if sys.hexversion >= 0x3000000:
	basestring = str

util.initialize_logger()

bad = create_color_func("BAD")

# A sane umask is needed for files that portage creates.
os.umask(0o22)


def repoman_main(argv):
	config_root = os.environ.get("PORTAGE_CONFIGROOT")
	repoman_settings = portage.config(config_root=config_root, local_config=False)

	if repoman_settings.get("NOCOLOR", "").lower() in ("yes", "true") or \
		repoman_settings.get('TERM') == 'dumb' or \
		not sys.stdout.isatty():
		nocolor()

	options, arguments = parse_args(
		sys.argv, qahelp, repoman_settings.get("REPOMAN_DEFAULT_OPTS", ""))

	if options.version:
		print("Portage", portage.VERSION)
		sys.exit(0)

	if options.experimental_inherit == 'y':
		# This is experimental, so it's non-fatal.
		qawarnings.add("inherit.missing")
		checks_init(experimental_inherit=True)

	# Set this to False when an extraordinary issue (generally
	# something other than a QA issue) makes it impossible to
	# commit (like if Manifest generation fails).
	can_force = True

	portdir, portdir_overlay, mydir = utilities.FindPortdir(repoman_settings)
	if portdir is None:
		sys.exit(1)

	myreporoot = os.path.basename(portdir_overlay)
	myreporoot += mydir[len(portdir_overlay):]

	vcs_settings = VCSSettings(options, repoman_settings)

	repo_settings = RepoSettings(
		config_root, portdir, portdir_overlay,
		repoman_settings, vcs_settings, options, qawarnings)
	repoman_settings = repo_settings.repoman_settings

	if 'digest' in repoman_settings.features and options.digest != 'n':
		options.digest = 'y'

	logging.debug("vcs: %s" % (vcs_settings.vcs,))
	logging.debug("repo config: %s" % (repo_settings.repo_config,))
	logging.debug("options: %s" % (options,))

	# It's confusing if these warnings are displayed without the user
	# being told which profile they come from, so disable them.
	env = os.environ.copy()
	env['FEATURES'] = env.get('FEATURES', '') + ' -unknown-features-warn'

	# Perform the main checks
	scanner = Scanner(repo_settings, myreporoot, config_root, options,
					vcs_settings, mydir, env)
	qatracker, can_force = scanner.scan_pkgs(can_force)

	commitmessage = None

	if options.if_modified == "y" and len(scanner.effective_scanlist) < 1:
		logging.warning("--if-modified is enabled, but no modified packages were found!")

	result = {
		# fail will be true if we have failed in at least one non-warning category
		'fail': 0,
		# warn will be true if we tripped any warnings
		'warn': 0,
		# full will be true if we should print a "repoman full" informational message
		'full': options.mode != 'full',
	}

	# early out for manifest generation
	if options.mode == "manifest":
		sys.exit(result['fail'])

	for x in qacats:
		if x not in qatracker.fails:
			continue
		result['warn'] = 1
		if x not in qawarnings:
			result['fail'] = 1

	if result['fail'] or \
		(result['warn'] and not (options.quiet or options.mode == "scan")):
		result['full'] = 0

	# Save QA output so that it can be conveniently displayed
	# in $EDITOR while the user creates a commit message.
	# Otherwise, the user would not be able to see this output
	# once the editor has taken over the screen.
	qa_output = io.StringIO()
	style_file = ConsoleStyleFile(sys.stdout)
	if options.mode == 'commit' and \
		(not commitmessage or not commitmessage.strip()):
		style_file.write_listener = qa_output
	console_writer = StyleWriter(file=style_file, maxcol=9999)
	console_writer.style_listener = style_file.new_styles

	f = formatter.AbstractFormatter(console_writer)

	format_outputs = {
		'column': format_qa_output_column,
		'default': format_qa_output
	}

	format_output = format_outputs.get(
		options.output_style, format_outputs['default'])
	format_output(f, qatracker.fails, result['full'], result['fail'], options, qawarnings)

	style_file.flush()
	del console_writer, f, style_file
	qa_output = qa_output.getvalue()
	qa_output = qa_output.splitlines(True)

	# output the results
	actions = Actions(repo_settings, options, scanner, vcs_settings)
	if actions.inform(can_force, result):
		# perform any other actions
		actions.perform(qa_output)

	sys.exit(0)
