#!/usr/bin/env python
# encoding: utf-8
# 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

from flask import request

from pyoauth2.provider import ResourceAuthorization
from pyoauth2.provider import ResourceProvider
from pyoauth2.provider import AuthorizationProvider


from gstack import db
from gstack.services import requester
from gstack.models.client import Client
from gstack.models.accesstoken import AccessToken
from gstack.models.refreshtoken import RefreshToken


class CloudstackAuthorizationProvider(AuthorizationProvider):

    def validate_client_id(self, client_id):
        return client_id is not None

    def validate_client_secret(self, client_id, client_secret):
        command = 'listCapabilities'
        args = {}
        cloudstack_response = requester.make_request(
            command,
            args,
            client_id,
            client_secret
        )

        if cloudstack_response:
            existing_client = Client.query.get(client_id)

            if existing_client is not None:
                existing_client.client_secret = client_secret
            else:
                client = Client(
                    client_id,
                    client_secret
                )
                db.session.add(client)

            db.session.commit()
            return True
        else:
            return False

    def validate_redirect_uri(self, client_id, redirect_uri):
        return True

    def validate_access(self):
        return True

    def validate_scope(self, client_id, scope):
        return True

    def persist_authorization_code(self, client_id, code, scope):
        return

    def persist_token_information(self, client_id, scope, access_token, token_type,
                                  expires_in, refresh_token, data):
        client = Client.query.get(client_id)
        if client is not None:
            existing_access_token = AccessToken.query.filter_by(
                client_id=client_id).first()
            existing_refresh_token = RefreshToken.query.filter_by(
                client_id=client_id).first()

            if existing_access_token is not None:
                existing_access_token.access_token = access_token
                existing_access_token.data = json.dumps(data)
                existing_access_token.expires_in = expires_in
            else:
                db.session.add(
                    AccessToken(
                        access_token, client_id, expires_in, json.dumps(data)
                    )
                )

            if existing_refresh_token is not None:
                existing_refresh_token.refresh_token = refresh_token
                existing_refresh_token.data = json.dumps(data)
            else:
                db.session.add(
                    RefreshToken(refresh_token, client_id, json.dumps(data)))

            db.session.commit()
            return True
        else:
            return False

    def from_authorization_code(self, client_id, code, scope):
        return {
            'client_id': client_id,
            'code': code,
            'scope': scope,
        }

    def from_refresh_token(self, client_id, refresh_token, scope):
        found_refresh_token = RefreshToken.query.get(refresh_token)
        if found_refresh_token is not None and found_refresh_token.data != 'false':
            data = json.loads(found_refresh_token.data)
            if (scope == '' or scope == data.get('scope')) and client_id == data.get('client_id'):
                return data
        else:
            return False

    def discard_authorization_code(self, client_id, code):
        return None

    def discard_refresh_token(self, client_id, refresh_token):
        found_refresh_token = RefreshToken.query.get(refresh_token)
        if found_refresh_token is not None:
            db.session.delete(found_refresh_token)
            db.session.commit()


class CloudstackResourceAuthorization(ResourceAuthorization):
    client_secret = None


class CloudstackResourceProvider(ResourceProvider):

    @property
    def authorization_class(self):
        return CloudstackResourceAuthorization

    def get_authorization_header(self):
        return request.headers.get('Authorization')

    def validate_access_token(self, access_token, authorization):
        found_access_token = AccessToken.query.get(access_token)
        if found_access_token is not None and found_access_token.data != 'false':
            access_token_data = json.loads(found_access_token.data)
            client = Client.query.get(access_token_data.get('client_id'))

            authorization.is_valid = True
            authorization.client_id = access_token_data.get('client_id')
            authorization.expires_in = access_token_data.get('expires_in')
            authorization.client_secret = client.client_secret
