#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
check_access - Determines whether access is permitted by a given ACL.
"""

__author__ = 'Jathan McCollum, Michael Shields'
__maintainer__ = 'Jathan McCollum'
__email__ = 'jathan.mccollum@teamaol.com'
__copyright__ = 'Copyright 2006-2013, AOL Inc.'
__version__ = '1.2'

import optparse
import sys
from simpleparse.error import ParserSyntaxError

from trigger.acl.parser import parse, TIP, Protocol, Term, Comment
from trigger.acl.tools import check_access, create_trigger_term

optp = optparse.OptionParser(description='''\
Determine whether access is permitted by a given ACL.  Exits 0 if permitted,
1 if edits are needed. Lists the terms that apply and what edits are needed.
Note that in order for the suggested edits feature to work, your policy must
end with an explicit deny.''',
    usage='%prog [opts] file source dest [protocol [port]]')
optp.add_option('-q', '--quiet', action='store_true', help='suppress output')
(opts, args) = optp.parse_args()

if not 3 <= len(args) <= 5:
    optp.error('not enough arguments')

acl_file = args[0]

source = dest = protocol = port = []

if args[1] == 'any':
    source = []
else:
    source = [TIP(args[1])]
if args[2] == 'any':
    dest = []
else:
    dest = [TIP(args[2])]

if len(args) <= 3:
    protocol = []
    port = []
elif len(args) == 4:
    try:
        protocol = [Protocol('tcp')]
        port = [int(args[3])]
    except ValueError:
        protocol = [Protocol(args[3])]
        port = []
else:
    protocol = [Protocol(args[3])]
    port = [int(args[4])]

new_term = create_trigger_term(
    source_ips=source, 
    dest_ips=dest, 
    source_ports=[], 
    dest_ports=port,
    protocols=protocol,
    name='sr_____',
)
new_term.modifiers['count'] = 'sr_____'
new_term.comments.append(Comment('check_access: ADD THIS TERM'))

try:
    acl = parse(file(acl_file))
    permitted = None
except ParserSyntaxError as e:
    etxt = str(e).split()
    sys.exit('Cannot parse %s:' % acl_file, ' '.join(etxt[1:]))

permitted = check_access(acl.terms, new_term, opts.quiet, format=acl.format,
                         acl_name=acl.name)

if permitted and not opts.quiet:
    print 'No edits needed.'

if permitted:
    sys.exit(0)
else:
    sys.exit(1)
