#!/usr/bin/env python

"""
Those tests checks the following requirements for the `projects.yaml` file:
    - Its syntax is valid
    - Each project definition should consist of the following mandatory parts:
        * project
        * description
      and could contain the following optional parts:
        * acl-config
        * upstream
      No other parts are possible.
    - All the projects listed in the `projects.yaml` file
      must be sorted alphabetically.
"""

import logging
import os
import sys

import git
import jsonschema
import yaml


logging.basicConfig(level=logging.INFO)

# Only lower case letters (a-z), digits (0-9), plus (+) and minus (-)
# and periods (.).
# They must be at least two characters long and must start with an
# alphanumeric character.
# https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source
# Additionally allow using underline symbol (required by openstack projects)

_PREFIX_PATTERN = '\A([a-z]([a-z]|\d|-)+/)*'
_NAMES_PATTERN = '([a-zA-Z]|\d)([a-zA-Z]|\d|[+-_.])+\Z'
PROJECT_NAME_PATTERN = _PREFIX_PATTERN + _NAMES_PATTERN

PROJECT_SCHEMA = {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "array",
    "items": {
        "type": "object",
        "additionalProperties": False,
        "properties": {
            "project": {
                "type": "string",
                "pattern": PROJECT_NAME_PATTERN
            },
            "description": {
                "type": "string"
            },
            "upstream": {
                "type": "string"
            },

            "acl-config": {
                "type": "string"
            }
        },
        "required": ["project", "description"]
    }
}


def parse_yaml_file(file_path):
    try:
        data = yaml.safe_load(open(file_path))
        if data is None:
            logging.error("File {0} is empty".format(file_path))
            sys.exit(1)
        return data
    except yaml.YAMLError as exc:
        msg = "File {0} could not be parsed: {1}".format(file_path, exc)
        logging.error(msg)
        sys.exit(1)


def validate_data_by_schema(data, file_path):
    try:
        jsonschema.validate(data, PROJECT_SCHEMA)
    except jsonschema.exceptions.ValidationError as exc:
        raise ValueError(_make_error_message(exc, file_path))


def _make_error_message(exc, file_path):
    value_path = []

    if exc.absolute_path:
        value_path.extend(exc.absolute_path)

    error_msg = "File '{0}', {1}".format(file_path, exc.message)

    if value_path:
        value_path = ' -> '.join(map(str, value_path))
        error_msg = '{0}, value path {1}'.format(error_msg, value_path)

    return error_msg


def check_duplicate_projects(data):
    projects_items = []
    for item in data:
        if item['project'] not in projects_items:
            projects_items.append(item['project'])
        else:
            msg = "Project '{0}' is duplicated".format(item['project'])
            raise ValueError(msg)


def check_alphabetical_order(data):
    for i in range(len(data) - 1):
        if not data[i]['project'] < data[i + 1]['project']:
            msg = ("Alphabetical order violation: project '{0}' must be "
                   "placed after '{1}'".format(data[i]['project'],
                                               data[i + 1]['project']))
            raise ValueError(msg)


def check_acls_config_path(data):
    valid = True

    for item in data:
        acl_config_path = item.get('acl-config')
        if not acl_config_path:
            continue
        # Allow to skip acls/ prefix in acl-config
        if acl_config_path[:4] != 'acls':
            acl_config_path = os.path.join('acls', acl_config_path)

        config_path = os.path.join(os.path.abspath(os.curdir),
                                   acl_config_path)
        if not os.path.isfile(config_path):
            logging.error("Config file for project '{0}' is not found "
                          "at {1}.".format(item.get('project'), config_path))
            valid = False
    if not valid:
        sys.exit(1)


def check_upstream_clonable(data):
    clonable = True

    for item in data:
        upstream_repo = item.get('upstream')
        if not upstream_repo:
            continue
        logging.info("Checking availability: {0}".format(upstream_repo))
        try:
            g = git.cmd.Git()
            g.ls_remote(upstream_repo)
        except git.exc.GitCommandError as e:
            err_msg = ("Unable to clone '{0}':"
                       "{1}".format(upstream_repo, str(e)))
            logging.error(err_msg)
            clonable = False

    if not clonable:
        sys.exit(1)


def run_checks(file_to_check):
    data = parse_yaml_file(file_to_check)
    validate_data_by_schema(data, file_to_check)
    check_duplicate_projects(data)
    check_alphabetical_order(data)
    check_acls_config_path(data)
    #check_upstream_clonable(data)


if __name__ == '__main__':
    if len(sys.argv) < 2:
        sys.stderr.write("Usage: {0} path/to/projects.yaml"
                         "\n".format(sys.argv[0]))
        sys.exit(1)
    run_checks(sys.argv[1])
