# Copyright 2018: Mirantis Inc.
# All Rights Reserved.
#
#    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 json
from logging.config import dictConfig

from flask import Flask, Response, jsonify, request

from prometheus_client import make_wsgi_app

from requests.exceptions import ConnectionError as RequestsConnectionError

from sf_notifier.helpers import alert_fields_and_action, create_file
from sf_notifier.salesforce.client import SESSION_FILE, SalesforceClient

from simple_salesforce.exceptions import SalesforceError

from simple_settings import settings

from werkzeug.wsgi import DispatcherMiddleware


dictConfig(settings.LOGGING)

app = Flask(__name__)
app_dispatch = DispatcherMiddleware(app, {
    '/metrics': make_wsgi_app()
})


create_file(SESSION_FILE)
sf_cli = SalesforceClient(settings.SF_CONFIG)


@app.route('/info', methods=['GET'])
def info():
    return jsonify({
        'version': settings.VERSION,
        'hashing': sf_cli.hash_func.__name__
    })


@app.route('/hook', methods=['POST'])
def webhook_receiver():

    try:
        data = json.loads(request.data)
    except ValueError:
        msg = 'Invalid request data: {}.'.format(request.data)
        app.logger.error(msg)
        return Response(json.dumps({'error': msg}),
                        status=400,
                        mimetype='application/json')

    app.logger.info('Received requests: {}'.format(data))

    cases = []
    for alert in data['alerts']:
        try:
            alert['labels']['env_id'] = sf_cli.environment
            fields, action = alert_fields_and_action(
                alert, add_links=settings.ADD_LINKS)
        except KeyError as key:
            msg = 'Alert misses {} key.'.format(key)
            app.logger.error(msg)
            return Response(json.dumps({'error': msg}),
                            status=400,
                            mimetype='application/json')

        if fields:
            try:
                cases.append(getattr(sf_cli, action)(*fields))
            except (SalesforceError, RequestsConnectionError) as err:
                msg = 'Salesforce request failure: {}.'.format(err)
                sf_cli.metrics['sf_error_count'].inc()
                app.logger.error(msg)
                return Response(json.dumps({'error': msg}),
                                status=500,
                                mimetype='application/json')

    if len(cases) == 1:
        return jsonify(cases[0])
    return jsonify(cases)


if __name__ == '__main__':
    app.run()
