#!python
#
# Copyright 2017 Nicholas de Jong  <contact[at]nicholasdejong.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os
import sys
import inspect
import argparse
from PfsenseFauxapi.PfsenseFauxapi import PfsenseFauxapi


class FauxAPIPyException(Exception):
    pass


class FauxAPIPy:

    name = 'FauxAPIPy'
    args = None
    argparse = None

    def __init__(self):
        self.argparse = argparse.ArgumentParser(description=self.name)

        group_call = self.argparse.add_argument_group('Call')
        group_call.add_argument('--host', type=str, metavar='<host>', required=False,
                            help='Host address of the target pfSense host with the PfsenseFauxapi package installed.')
        group_call.add_argument('--apikey', type=str, metavar='<key>', required=False,
                            help='FauxAPI apikey value - alternatively via the FAUXAPI_APIKEY environment variable.')
        group_call.add_argument('--apisecret', type=str, metavar='<secret>', required=False,
                            help='FauxAPI apisecret value - alternatively via the FAUXAPI_APISECRET environment variable.')
        group_call.add_argument('--verified-ssl', action='store_true', default=False,
                            help='Enable SSL certificate checks - default does NOT check SSL certificates.')
        group_call.add_argument('--debug', action='store_true', default=False,
                            help='Enable debug response from the remote FauxAPI - helpful in tracking down issues.')
        group_call.add_argument('function', metavar='<function>', type=str, nargs='+',
                            help='The FauxAPI function being called')
        group_call.add_argument('function_args', metavar='<function-args>', type=str, nargs='?',
                            help='Arguments to the function, space separated')

        self.args = self.argparse.parse_args()

    def main(self):

        if self.args.apikey:
            apikey = self.args.apikey
        elif os.getenv('FAUXAPI_APIKEY'):
            apikey = os.getenv('FAUXAPI_APIKEY')
        else:
            self.argparse.print_help(sys.stderr)
            sys.exit(1)

        if self.args.apisecret:
            apisecret = self.args.apisecret
        elif os.getenv('FAUXAPI_APIKEY'):
            apisecret = os.getenv('FAUXAPI_APIKEY')
        else:
            self.argparse.print_help(sys.stderr)
            sys.exit(1)

        # munge the function args
        if type(self.args.function_args) is list:
            self.args.function.extend(self.args.function_args)

        function = self.args.function[0]
        function_args = self.args.function[1:]

        fauxapi = PfsenseFauxapi(
            host=self.args.host,
            apikey=apikey,
            apisecret=apisecret,
            use_verified_https=self.args.verified_ssl,
            debug=self.args.debug
        )

        if function not in dir(fauxapi):
            print()
            print('ERROR: Requested "{}" is not a known function'.format(function))
            print()
            print('Functions available:-')

            funcs = inspect.getmembers(fauxapi, predicate=inspect.ismethod)
            funcs.sort()

            for f, _ in funcs:
                if f[0] != '_':
                    print(' - {}'.format(f))
            print()
            sys.exit(1)

        result = getattr(fauxapi, function)()
        print(result)


if __name__ == '__main__':
    FauxAPIPy().main()
