# 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 sf_notifier.helpers import alert_fields_and_action
from sf_notifier.salesforce.client import SalesforceClient

from simple_salesforce.exceptions import SalesforceMalformedRequest

from simple_settings import settings

from werkzeug.wsgi import DispatcherMiddleware


dictConfig(settings.LOGGING)

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

sf_cli = SalesforceClient(settings.SF_CONFIG)


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


@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:
            fields, action = alert_fields_and_action(alert, sf_cli.environment)
        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 SalesforceMalformedRequest 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()
