#!/usr/bin/env python3
# -*- coding: 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.

"""
This is the OpenAPI validator library.
Validates input using the OpenAPI specification version 3 from
https://github.com/OAI/OpenAPI-Specification (a simplified version, ahem)
"""

import yaml
import json
import functools
import operator
import re


class BlockyHTTPError(Exception):
    def __init__(self, code, message):
        self.code = code
        self.message = message
        

class OpenAPIException(Exception):
    def __init__(self, message):
        self.message = message

# Python type names to JSON type names
py2JSON = {
    'int':      'integer',
    'float':    'float',
    'str':      'string',
    'list':     'array',
    'dict':     'object',
    'bool':     'boolean'
}

mcolors = {
    'PUT':      '#fca130',
    'DELETE':   '#f93e3e',
    'GET':      '#61affe',
    'POST':     '#49cc5c',
    'PATCH':    '#d5a37e'
}
        
class OpenAPI():
    def __init__(self, APIFile):
        """ Instantiates an OpenAPI validator given a YAML specification"""
        if APIFile.endswith(".json") or APIFile.endswith(".js"):
            self.API = json.load(open(APIFile))
        else:
            self.API = yaml.load(open(APIFile))
        
    def validateType(self, field, value, ftype):
        """ Validate a single field value against an expected type """
        
        # Get type of value, convert to JSON name of type.
        pyType = type(value).__name__
        jsonType = py2JSON[pyType] if pyType in py2JSON else pyType
        
        # Check if type matches
        if ftype != jsonType:
            raise OpenAPIException("OpenAPI mismatch: Field '%s' was expected to be %s, but was really %s!" % (field, ftype, jsonType))
        
    def validateSchema(self, pdef, formdata, schema = None):
        """ Validate (sub)parameters against OpenAPI specs """
        
        # allOf: list of schemas to validate against
        if 'allOf' in pdef:
            for subdef in pdef['allOf']:
                self.validateSchema(subdef, formdata)
        
        where = "JSON body"
        # Symbolic link??
        if 'schema' in pdef:
            schema = pdef['schema']['$ref']
        if '$ref' in pdef:
            schema = pdef['$ref']
        if schema:
            # #/foo/bar/baz --> dict['foo']['bar']['baz']
            pdef = functools.reduce(operator.getitem, schema.split('/')[1:], self.API)
            where = "item matching schema %s" % schema
        
        # Check that all required fields are present
        if 'required' in pdef:
            for field in pdef['required']:
                if not field in formdata:
                    raise OpenAPIException("OpenAPI mismatch: Missing input field '%s' in %s!" % (field, where))
        
        # Now check for valid format of input data
        for field in formdata:
            if 'properties' not in pdef or field not in pdef['properties'] :
                raise OpenAPIException("Unknown input field '%s' in %s!" % (field, where))
            if 'type' not in pdef['properties'][field]:
                raise OpenAPIException("OpenAPI mismatch: Field '%s' was found in api.yaml, but no format was specified in specs!" % field)
            ftype = pdef['properties'][field]['type']
            self.validateType(field, formdata[field], ftype)
            
            # Validate sub-arrays
            if ftype == 'array' and 'items' in pdef['properties'][field]:
                for item in formdata[field]:
                    if '$ref' in pdef['properties'][field]['items']:
                        self.validateSchema(pdef['properties'][field]['items'], item)
                    else:
                        self.validateType(field, formdata[field], pdef['properties'][field]['items']['type'])
            
            # Validate sub-hashes
            if ftype == 'hash' and 'schema' in pdef['properties'][field]:
                self.validateSchema(pdef['properties'][field], formdata[field])
    def validateParameters(self, defs, formdata):
        #
        pass
        
    def validate(self, method = "GET", path = "/foo", formdata = None):
        """ Validate the request method and input data against the OpenAPI specification """
        
        # Make sure we're not dealing with a dynamic URL.
        # If we find /foo/{key}, we fold that into the form data
        # and process as if it's a json input field for now.
        if not self.API['paths'].get(path):
            for xpath in self.API['paths']:
                pathRE = re.sub(r"\{(.+?)\}", r"(?P<\1>[^/]+)", xpath)
                m = re.match(pathRE, path)
                if m:
                    for k,v  in m.groupdict().items():
                        formdata[k] = v
                    path = xpath
                    break
                
        if self.API['paths'].get(path):
            defs = self.API['paths'].get(path)
            method = method.lower()
            if method in defs:
                mdefs = defs[method]
                if formdata and 'parameters' in mdefs:
                    self.validateParameters(mdefs['parameters'], formdata)
                elif formdata and 'requestBody' not in mdefs:
                    raise OpenAPIException("OpenAPI mismatch: JSON data is now allowed for this request type")
                elif formdata and 'requestBody' in mdefs and 'content' in mdefs['requestBody']:
                    
                    # SHORTCUT: We only care about JSON input for Kibble! Disregard other types
                    if not 'application/json' in mdefs['requestBody']['content']:
                        raise OpenAPIException ("OpenAPI mismatch: API endpoint accepts input, but no application/json definitions found in api.yaml!")
                    jdefs = mdefs['requestBody']['content']['application/json']
                    
                    # Check that required params are here
                    self.validateSchema(jdefs, formdata)
                
            else:
                raise OpenAPIException ("OpenAPI mismatch: Method %s is not registered for this API" % method)
        else:
            raise OpenAPIException("OpenAPI mismatch: Unknown API path '%s'!" % path)

    def dumpExamples(self, pdef, array = False):
        schema = None
        if 'schema' in pdef:
            if 'type' in pdef['schema'] and pdef['schema']['type'] == 'array':
                array = True
                schema = pdef['schema']['items']['$ref']
            else:
                schema = pdef['schema']['$ref']
        if '$ref' in pdef:
            schema = pdef['$ref']
        if schema:
            # #/foo/bar/baz --> dict['foo']['bar']['baz']
            pdef = functools.reduce(operator.getitem, schema.split('/')[1:], self.API)
        js = {}
        desc = {}
        if 'properties' in pdef:
            for k, v in pdef['properties'].items():
                if 'description' in v:
                    desc[k] = [v['type'], v['description']]
                if 'example' in v:
                    js[k] = v['example']
                elif 'items' in v:
                    if v['type'] == 'array':
                        js[k], foo = self.dumpExamples(v['items'], True)
                    else:
                        js[k], foo = self.dumpExamples(v['items'])
        return [js if not array else [js], desc]
        
    def toHTML(self):
        """ Blurps out the specs in a pretty HTML blob """
        print("""
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
""")
        li = "<h3>Overview:</h3><ul style='font-size: 12px; font-family: Open Sans, sans-serif;'>"
        for path, spec in sorted(self.API['paths'].items()):
            for method, mspec in sorted(spec.items()):
                method = method.upper()
                summary = mspec.get('summary', 'No summary available')
                linkname = "%s%s" % (method.lower(), path.replace('/', '-'))
                li += "<li><a href='#%s'>%s %s</a>: %s</li>\n" % (linkname, method, path, summary)
        li += "</ul>"
        print(li)
        for path, spec in sorted(self.API['paths'].items()):
            for method, mspec in sorted(spec.items()):
                method = method.upper()
                summary = mspec.get('summary', 'No summary available')
                resp = ""
                inp = ""
                inpvars = ""
                linkname = "%s%s" % (method.lower(), path.replace('/', '-'))
                if 'responses' in mspec:
                    for code, cresp in sorted(mspec['responses'].items()):
                        for ctype, pdef in cresp['content'].items():
                            xjs, desc = self.dumpExamples(pdef)
                            js = json.dumps(xjs, indent = 4)
                            resp += "<div style='float: left; width: 90%%;'><pre style='width: 600px;'><b>%s</b>:\n%s</pre>\n</div>\n" % (code, js)
                
                if 'requestBody' in mspec:
                    for ctype, pdef in mspec['requestBody']['content'].items():
                        xjs, desc = self.dumpExamples(pdef)
                        if desc:
                            for k, v in desc.items():
                                inpvars += "<kbd><b>%s:</b></kbd> (%s) <span style='font-size: 12px; font-family: Open Sans, sans-serif;'>%s</span><br/>\n" % (k, v[0], v[1])
                        js = json.dumps(xjs, indent = 4)
                        inp += "<div style='float: left; width: 90%%;'><h4>Input examples:</h4><blockquote><pre style='width: 600px;'><b>%s</b>:\n%s</pre></blockquote>\n</div>" % (ctype, js)
                    
                if inpvars:
                    inpvars = "<div style='float: left; width: 90%%;'><blockquote><pre style='width: 600px;'>%s</pre>\n</blockquote></div>" % inpvars

                
                print("""
                      <div id="%s" style="margin: 20px; display: flex; box-sizing: border-box; width: 900px; border-radius: 6px; border: 1px solid %s; font-family: sans-serif; background: %s30;">
                        <div style="min-height: 32px;">
                          <!-- method -->
                          
                          <div style="float: left; align-items: center; margin: 4px; border-radius: 5px; text-align: center; padding-top: 4px; height: 20px; width: 100px; color: #FFF; font-weight: bold; background: %s;">%s</div>
                          
                          <!-- path and summary -->
                          <span style="display: flex; padding-top: 6px;"><kbd><strong>%s</strong></kbd></span>
                          <div style="box-sizing: border-box; flex: 1; font-size: 13px; font-family: Open Sans, sans-serif; float: left; padding-top: 6px; margin-left: 20px;">
                          %s</div>
                          <div style="float: left; width: 90%%;display: %s; ">
                            <h4>JSON parameters:</h4>
                            %s
                            <br/>
                            %s
                          </div>
                          <div style="float: left; width: 90%%; ">
                            <h4>Response examples:</h4>
                            <blockquote>%s</blockquote>
                          </div>
                        </div>
                      </div>
                      """ % (linkname, mcolors[method], mcolors[method], mcolors[method], method, path, summary, "block" if inp else "none", inpvars, inp, resp))
                #print("%s %s: %s" % (method.upper(), path, mspec['summary']))
        print("</body></html>")