#!/usr/bin/env python

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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 json
import logging
import os

from requests import Session, Response

from apache_ranger.exceptions                 import RangerServiceException
from apache_ranger.model.ranger_base          import RangerBase
from apache_ranger.model.ranger_role          import RangerRole
from apache_ranger.model.ranger_policy        import RangerPolicy
from apache_ranger.model.ranger_service       import RangerService
from apache_ranger.model.ranger_service_def   import RangerServiceDef
from apache_ranger.model.ranger_security_zone import RangerSecurityZone
from apache_ranger.utils                      import *



LOG = logging.getLogger(__name__)


class RangerClient:
    def __init__(self, url, auth):
        self.url          = url
        self.session      = Session()
        self.session.auth = auth

        logging.getLogger("requests").setLevel(logging.WARNING)


    # Service Definition APIs
    def create_service_def(self, serviceDef):
        resp = self.__call_api(RangerClient.CREATE_SERVICEDEF, request_data=serviceDef)

        return type_coerce(resp, RangerServiceDef)

    def update_service_def_by_id(self, serviceDefId, serviceDef):
        resp = self.__call_api(RangerClient.UPDATE_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }), request_data=serviceDef)

        return type_coerce(resp, RangerServiceDef)

    def update_service_def(self, serviceDefName, serviceDef):
        resp = self.__call_api(RangerClient.UPDATE_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }), request_data=serviceDef)

        return type_coerce(resp, RangerServiceDef)

    def delete_service_def_by_id(self, serviceDefId):
        self.__call_api(RangerClient.DELETE_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }))

    def delete_service_def(self, serviceDefName):
        self.__call_api(RangerClient.DELETE_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }))

    def get_service_def_by_id(self, serviceDefId):
        resp = self.__call_api(RangerClient.GET_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }))

        return type_coerce(resp, RangerServiceDef)

    def get_service_def(self, serviceDefName):
        resp = self.__call_api(RangerClient.GET_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }))

        return type_coerce(resp, RangerServiceDef)

    def find_service_defs(self, filter=None):
        if filter is None:
            filter = {}

        resp = self.__call_api(RangerClient.FIND_SERVICEDEFS, filter)

        return type_coerce_list(resp, RangerServiceDef)


    # Service APIs
    def create_service(self, service):
        resp = self.__call_api(RangerClient.CREATE_SERVICE, request_data=service)

        return type_coerce(resp, RangerService)

    def get_service_by_id(self, serviceId):
        resp = self.__call_api(RangerClient.GET_SERVICE_BY_ID.format_path({ 'id': serviceId }))

        return type_coerce(resp, RangerService)

    def get_service(self, serviceName):
        resp = self.__call_api(RangerClient.GET_SERVICE_BY_NAME.format_path({ 'name': serviceName }))

        return type_coerce(resp, RangerService)

    def update_service_by_id(self, serviceId, service):
        resp = self.__call_api(RangerClient.UPDATE_SERVICE_BY_ID.format_path({ 'id': serviceId }), request_data=service)

        return type_coerce(resp, RangerService)

    def update_service(self, serviceName, service):
        resp = self.__call_api(RangerClient.UPDATE_SERVICE_BY_NAME.format_path({ 'name': serviceName }), request_data=service)

        return type_coerce(resp, RangerService)

    def delete_service_by_id(self, serviceId):
        self.__call_api(RangerClient.DELETE_SERVICE_BY_ID.format_path({ 'id': serviceId }))

    def delete_service(self, serviceName):
        self.__call_api(RangerClient.DELETE_SERVICE_BY_NAME.format_path({ 'name': serviceName }))

    def find_services(self, filter=None):
        if filter is None:
            filter = {}

        resp = self.__call_api(RangerClient.FIND_SERVICES, filter)

        return type_coerce_list(resp, RangerService)


    # Policy APIs
    def create_policy(self, policy):
        resp = self.__call_api(RangerClient.CREATE_POLICY, request_data=policy)

        return type_coerce(resp, RangerPolicy)

    def get_policy_by_id(self, policyId):
        resp = self.__call_api(RangerClient.GET_POLICY_BY_ID.format_path({ 'id': policyId }))

        return type_coerce(resp, RangerPolicy)

    def get_policy(self, serviceName, policyName):
        resp = self.__call_api(RangerClient.GET_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}))

        return type_coerce(resp, RangerPolicy)

    def get_policies_in_service(self, serviceName):
        resp = self.__call_api(RangerClient.GET_POLICIES_IN_SERVICE.format_path({ 'serviceName': serviceName }))

        return type_coerce_list(resp, RangerPolicy)

    def update_policy_by_id(self, policyId, policy):
        resp = self.__call_api(RangerClient.UPDATE_POLICY_BY_ID.format_path({ 'id': policyId }), request_data=policy)

        return type_coerce(resp, RangerPolicy)

    def update_policy(self, serviceName, policyName, policy):
        resp = self.__call_api(RangerClient.UPDATE_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}), request_data=policy)

        return type_coerce(resp, RangerPolicy)

    def apply_policy(self, policy):
        resp = self.__call_api(RangerClient.APPLY_POLICY, request_data=policy)

        return type_coerce(resp, RangerPolicy)

    def delete_policy_by_id(self, policyId):
        self.__call_api(RangerClient.DELETE_POLICY_BY_ID.format_path({ 'id': policyId }))

    def delete_policy(self, serviceName, policyName):
        self.__call_api(RangerClient.DELETE_POLICY_BY_NAME, { 'servicename': serviceName, 'policyname': policyName })

    def find_policies(self, filter={}):
        resp = self.__call_api(RangerClient.FIND_POLICIES, filter)

        return type_coerce_list(resp, RangerPolicy)


    # SecurityZone APIs
    def create_security_zone(self, securityZone):
        resp = self.__call_api(RangerClient.CREATE_ZONE, request_data=securityZone)

        return type_coerce(resp, RangerSecurityZone)

    def update_security_zone_by_id(self, zoneId, securityZone):
        resp = self.__call_api(RangerClient.UPDATE_ZONE_BY_ID.format_path({ 'id': zoneId }), request_data=securityZone)

        return type_coerce(resp, RangerSecurityZone)

    def update_security_zone(self, zoneName, securityZone):
        resp = self.__call_api(RangerClient.UPDATE_ZONE_BY_NAME.format_path({ 'name': zoneName }), request_data=securityZone)

        return type_coerce(resp, RangerSecurityZone)

    def delete_security_zone_by_id(self, zoneId):
        self.__call_api(RangerClient.DELETE_ZONE_BY_ID.format_path({ 'id': zoneId }))

    def delete_security_zone(self, zoneName):
        self.__call_api(RangerClient.DELETE_ZONE_BY_NAME.format_path({ 'name': zoneName }))

    def get_security_zone_by_id(self, zoneId):
        resp = self.__call_api(RangerClient.GET_ZONE_BY_ID.format_path({ 'id': zoneId }))

        return type_coerce(resp, RangerSecurityZone)

    def get_security_zone(self, zoneName):
        resp = self.__call_api(RangerClient.GET_ZONE_BY_NAME.format_path({ 'name': zoneName }))

        return type_coerce(resp, RangerSecurityZone)

    def find_security_zones(self, filter={}):
        resp = self.__call_api(RangerClient.FIND_ZONES, filter)

        return type_coerce_list(resp, RangerSecurityZone)


    # Role APIs
    def create_role(self, serviceName, role):
        resp = self.__call_api(RangerClient.CREATE_ROLE, { 'serviceName': serviceName }, role)

        return type_coerce(resp, RangerRole)

    def update_role(self, roleId, role):
        resp = self.__call_api(RangerClient.UPDATE_ROLE_BY_ID.format_path({ 'id': roleId }), request_data=role)

        return type_coerce(resp, RangerRole)

    def delete_role_by_id(self, roleId):
        self.__call_api(RangerClient.DELETE_ROLE_BY_ID.format_path({ 'id': roleId }))

    def delete_role(self, roleName, execUser, serviceName):
        self.__call_api(RangerClient.DELETE_ROLE_BY_NAME.format_path({ 'name': roleName }), { 'execUser': execUser, 'serviceName': serviceName })

    def get_role_by_id(self, roleId):
        resp = self.__call_api(RangerClient.GET_ROLE_BY_ID.format_path({ 'id': roleId }))

        return type_coerce(resp, RangerRole)

    def get_role(self, roleName, execUser, serviceName):
        resp = self.__call_api(RangerClient.GET_ROLE_BY_NAME.format_path({ 'name': roleName }), { 'execUser': execUser, 'serviceName': serviceName })

        return type_coerce(resp, RangerRole)

    def get_all_role_names(self, execUser, serviceName):
        resp = self.__call_api(RangerClient.GET_ALL_ROLE_NAMES.format_path({ 'name': serviceName }), { 'execUser': execUser, 'serviceName': serviceName })

        return resp

    def get_user_roles(self, user):
        ret = self.__call_api(RangerClient.GET_USER_ROLES.format_path({ 'name': user }))

        return list(ret) if ret is not None else None

    def find_roles(self, filter={}):
        resp = self.__call_api(RangerClient.FIND_ROLES, filter)

        return type_coerce_list(resp, RangerRole)

    def grant_role(self, serviceName, request):
        resp = self.__call_api(RangerClient.GRANT_ROLE.format_path({ 'name': serviceName }), request_data=request)

        return type_coerce(resp, RESTResponse)

    def revoke_role(self, serviceName, request):
        resp = self.__call_api(RangerClient.REVOKE_ROLE.format_path({ 'name': serviceName }), request_data=request)

        return type_coerce(resp, RESTResponse)


    # Admin APIs
    def delete_policy_deltas(self, days, reloadServicePoliciesCache):
        self.__call_api(RangerClient.DELETE_POLICY_DELTAS, { 'days': days, 'reloadServicePoliciesCache': reloadServicePoliciesCache})



    def __call_api(self, api, query_params=None, request_data=None):
        ret    = None
        params = { 'headers': { 'Accept': api.consumes, 'Content-type': api.produces } }

        if query_params:
            params['params'] = query_params

        if request_data:
            params['data'] = json.dumps(request_data)

        path = os.path.join(self.url, api.path)

        if LOG.isEnabledFor(logging.DEBUG):
            LOG.debug("------------------------------------------------------")
            LOG.debug("Call         : %s %s", api.method, path)
            LOG.debug("Content-type : %s", api.consumes)
            LOG.debug("Accept       : %s", api.produces)

        response = None

        if api.method == HttpMethod.GET:
            response = self.session.get(path, **params)
        elif api.method == HttpMethod.POST:
            response = self.session.post(path, **params)
        elif api.method == HttpMethod.PUT:
            response = self.session.put(path, **params)
        elif api.method == HttpMethod.DELETE:
            response = self.session.delete(path, **params)

        if LOG.isEnabledFor(logging.DEBUG):
            LOG.debug("HTTP Status: %s", response.status_code if response else "None")

        if response is None:
            ret = None
        elif response.status_code == api.expected_status:
            try:
                if response.content is not None:
                    if LOG.isEnabledFor(logging.DEBUG):
                        LOG.debug("<== __call_api(%s, %s, %s), result=%s", vars(api), params, request_data, response)

                        LOG.debug(response.json())

                    ret = response.json()
                else:
                    ret = None
            except Exception as e:
                print(e)

                LOG.exception("Exception occurred while parsing response with msg: %s", e)

                raise RangerServiceException(api, response)
        elif response.status_code == HTTPStatus.SERVICE_UNAVAILABLE:
            LOG.error("Ranger admin unavailable. HTTP Status: %s", HTTPStatus.SERVICE_UNAVAILABLE)

            ret = None
        else:
            raise RangerServiceException(api, response)

        return ret


    # URIs
    URI_BASE                = "service/public/v2/api"

    URI_SERVICEDEF          = URI_BASE + "/servicedef"
    URI_SERVICEDEF_BY_ID    = URI_SERVICEDEF + "/{id}"
    URI_SERVICEDEF_BY_NAME  = URI_SERVICEDEF + "/name/{name}"

    URI_SERVICE             = URI_BASE + "/service"
    URI_SERVICE_BY_ID       = URI_SERVICE + "/{id}"
    URI_SERVICE_BY_NAME     = URI_SERVICE + "/name/{name}"
    URI_POLICIES_IN_SERVICE = URI_SERVICE + "/{serviceName}/policy"

    URI_POLICY              = URI_BASE + "/policy"
    URI_APPLY_POLICY        = URI_POLICY + "/apply"
    URI_POLICY_BY_ID        = URI_POLICY + "/{id}"
    URI_POLICY_BY_NAME      = URI_SERVICE + "/{serviceName}/policy/{policyName}"

    URI_ROLE                = URI_BASE + "/roles"
    URI_ROLE_NAMES          = URI_ROLE + "/names"
    URI_ROLE_BY_ID          = URI_ROLE + "/{id}"
    URI_ROLE_BY_NAME        = URI_ROLE + "/name/{name}"
    URI_USER_ROLES          = URI_ROLE + "/user/{name}"
    URI_GRANT_ROLE          = URI_ROLE + "/grant/{name}"
    URI_REVOKE_ROLE         = URI_ROLE + "/revoke/{name}"

    URI_ZONE                = URI_BASE + "/zones"
    URI_ZONE_BY_ID          = URI_ZONE + "/{id}"
    URI_ZONE_BY_NAME        = URI_ZONE + "/name/{name}"

    URI_PLUGIN_INFO         = URI_BASE + "/plugins/info"
    URI_POLICY_DELTAS       = URI_BASE + "/server/policydeltas"

    # APIs
    CREATE_SERVICEDEF         = API(URI_SERVICEDEF, HttpMethod.POST, HTTPStatus.OK)
    UPDATE_SERVICEDEF_BY_ID   = API(URI_SERVICEDEF_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
    UPDATE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
    DELETE_SERVICEDEF_BY_ID   = API(URI_SERVICEDEF_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    DELETE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    GET_SERVICEDEF_BY_ID      = API(URI_SERVICEDEF_BY_ID, HttpMethod.GET, HTTPStatus.OK)
    GET_SERVICEDEF_BY_NAME    = API(URI_SERVICEDEF_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
    FIND_SERVICEDEFS          = API(URI_SERVICEDEF, HttpMethod.GET, HTTPStatus.OK)

    CREATE_SERVICE            = API(URI_SERVICE, HttpMethod.POST, HTTPStatus.OK)
    UPDATE_SERVICE_BY_ID      = API(URI_SERVICE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
    UPDATE_SERVICE_BY_NAME    = API(URI_SERVICE_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
    DELETE_SERVICE_BY_ID      = API(URI_SERVICE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    DELETE_SERVICE_BY_NAME    = API(URI_SERVICE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    GET_SERVICE_BY_ID         = API(URI_SERVICE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
    GET_SERVICE_BY_NAME       = API(URI_SERVICE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
    FIND_SERVICES             = API(URI_SERVICE, HttpMethod.GET, HTTPStatus.OK)

    CREATE_POLICY             = API(URI_POLICY, HttpMethod.POST, HTTPStatus.OK)
    UPDATE_POLICY_BY_ID       = API(URI_POLICY_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
    UPDATE_POLICY_BY_NAME     = API(URI_POLICY_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
    APPLY_POLICY              = API(URI_APPLY_POLICY, HttpMethod.POST, HTTPStatus.OK)
    DELETE_POLICY_BY_ID       = API(URI_POLICY_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    DELETE_POLICY_BY_NAME     = API(URI_POLICY, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    GET_POLICY_BY_ID          = API(URI_POLICY_BY_ID, HttpMethod.GET, HTTPStatus.OK)
    GET_POLICY_BY_NAME        = API(URI_POLICY_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
    GET_POLICIES_IN_SERVICE   = API(URI_POLICIES_IN_SERVICE, HttpMethod.GET, HTTPStatus.OK)
    FIND_POLICIES             = API(URI_POLICY, HttpMethod.GET, HTTPStatus.OK)

    CREATE_ZONE               = API(URI_ZONE, HttpMethod.POST, HTTPStatus.OK)
    UPDATE_ZONE_BY_ID         = API(URI_ZONE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
    UPDATE_ZONE_BY_NAME       = API(URI_ZONE_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
    DELETE_ZONE_BY_ID         = API(URI_ZONE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    DELETE_ZONE_BY_NAME       = API(URI_ZONE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    GET_ZONE_BY_ID            = API(URI_ZONE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
    GET_ZONE_BY_NAME          = API(URI_ZONE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
    FIND_ZONES                = API(URI_ZONE, HttpMethod.GET, HTTPStatus.OK)

    CREATE_ROLE               = API(URI_ROLE, HttpMethod.POST, HTTPStatus.OK)
    UPDATE_ROLE_BY_ID         = API(URI_ROLE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
    DELETE_ROLE_BY_ID         = API(URI_ROLE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    DELETE_ROLE_BY_NAME       = API(URI_ROLE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
    GET_ROLE_BY_ID            = API(URI_ROLE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
    GET_ROLE_BY_NAME          = API(URI_ROLE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
    GET_ALL_ROLE_NAMES        = API(URI_ROLE_NAMES, HttpMethod.GET, HTTPStatus.OK)
    GET_USER_ROLES            = API(URI_USER_ROLES, HttpMethod.GET, HTTPStatus.OK)
    GRANT_ROLE                = API(URI_GRANT_ROLE, HttpMethod.PUT, HTTPStatus.OK)
    REVOKE_ROLE               = API(URI_REVOKE_ROLE, HttpMethod.PUT, HTTPStatus.OK)
    FIND_ROLES                = API(URI_ROLE, HttpMethod.GET, HTTPStatus.OK)

    GET_PLUGIN_INFO           = API(URI_PLUGIN_INFO, HttpMethod.GET, HTTPStatus.OK)
    DELETE_POLICY_DELTAS      = API(URI_POLICY_DELTAS, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)


class Message(RangerBase):
    def __init__(self, attrs=None):
        if attrs is None:
            attrs = {}

        RangerBase.__init__(self, attrs)

        self.name      = attrs.get('name')
        self.rbKey     = attrs.get('rbKey')
        self.message   = attrs.get('message')
        self.objectId  = attrs.get('objectId')
        self.fieldName = attrs.get('fieldName')


class RESTResponse(RangerBase):
    def __init__(self, attrs=None):
        if attrs is None:
            attrs = {}

        RangerBase.__init__(self, attrs)

        self.httpStatusCode = attrs.get('httpStatusCode')
        self.statusCode     = attrs.get('statusCode')
        self.msgDesc        = attrs.get('msgDesc')
        self.messageList    = non_null(attrs.get('messageList'), [])

    def type_coerce_attrs(self):
        super(RangerPolicy, self).type_coerce_attrs()

        self.messageList = type_coerce_dict(self.messageList, Message)
