#!/usr/bin/env python3

import sys
import yaml

def withResponse(resp):
    for x in resp:
        if "schema" in resp[x]:
            return True
    return False

filename="urykhy1-queue-1.0.0-swagger.yaml"
with open(filename, 'r') as stream:
    doc = yaml.safe_load(stream)

print ("/*")
print ("-----------------------------------------")
print ("AUTOGENERATED INTERFACE FILE, DO NOT EDIT")
print ("-----------------------------------------")
print ("")
print ("")
print (doc["info"]["title"])
print ("")
print (doc["info"]["description"])
print ("*/")
print ("package main")
print ("import \"github.com/gorilla/mux\"")
print ("import log \"github.com/sirupsen/logrus\"")
print ("")
print ("// CreateRouter creates swagger api router")
print ("func CreateRouter(log *log.Logger) *mux.Router {")
print ("r := mux.NewRouter()")
for fname in doc["paths"]:
    for method in doc["paths"][fname]:
        d = doc["paths"][fname][method]
        print ("r.Path(\"{}\").Methods(\"{}\").HandlerFunc(func (w http.ResponseWriter, r *http.Request)".format(doc["basePath"] + fname, method),"{")
        print ("// {}".format(d["summary"]))
        params = []
        if "parameters" in d:
            if method == "get":
                print ("q := r.URL.Query()")
                checkQuery = "q"
                getQuery = "q.Get"
            else:
                print ("if err := r.ParseForm(); err != nil {")
                print ("log.WithField(\"method\", \"{}\").Warn(\"bad form: \", err)".format(fname))
                print ("w.WriteHeader(http.StatusBadRequest)")
                print ("return")
                print ("}")
                checkQuery = "r.Form"
                getQuery = "r.FormValue"

            for param in d["parameters"]:
                #print (param)
                if param["in"] != "query":
                    sys.stderr.write("only in 'query' parameters are supported")
                    sys.exit(-1)
                name = ''.join(x for x in param["name"].title() if not x == "_")
                name = name.replace("Id","ID")
                print ("var {} *{}".format(name, "int64" if param["type"] == "integer" else "string"))
                print ("{")

                print ("_, ok := {}[\"{}\"]".format(checkQuery, param["name"]))
                print ("if ok {")
                if param["type"] == "integer":
                    print ("{}Tmp, err := strconv.ParseInt({}(\"{}\"), 10, 64)".format(name, getQuery, param["name"]))
                    print ("if err != nil {")
                    print ("log.WithField(\"method\", \"{}\").Warn(\"bad param {}\")".format(fname, param["name"]))
                    print ("w.WriteHeader(http.StatusBadRequest)")
                    print ("return")
                    print ("}")
                    print ("{0} = &{0}Tmp".format(name))
                else:
                    print ("{}Tmp := {}(\"{}\")".format(name, getQuery, param["name"]))
                    print ("{0} = &{0}Tmp".format(name))
                if "required" in param and param["required"] == True:
                    print ("} else {")
                    print ("log.WithField(\"method\", \"{}\").Warn(\"no required param {}\")".format(fname, param["name"]))
                    print ("w.WriteHeader(http.StatusBadRequest)")
                    print ("return")
                print ("}")
                print ("}")
                params.append("{}".format(name))

        if "responses" in d and withResponse(d["responses"]):
            wr = True
            print ("code, resp, err := {}({})".format(d["operationId"], ",".join(params)))
        else:
            wr = False
            print ("code, err := {}({})".format(d["operationId"], ",".join(params)))
        print ("if err != nil {")
        print ("w.WriteHeader(code)")
        print ("log.WithField(\"method\", \"{}\").Error(err)".format(fname))
        print ("return")
        print ("}")
        if wr:
            print ("if resp != nil {")
            print ("jresp, err := json.Marshal(resp)")
            print ("if err != nil {")
            print ("log.WithField(\"method\", \"{}\").Error(\"fail to format result\")".format(fname))
            print ("w.WriteHeader(http.StatusInternalServerError)")
            print ("return")
            print ("}")
            print ("w.WriteHeader(code)")
            print ("w.Write(jresp)")
            print ("return")
            print ("}")
        print ("w.WriteHeader(code)")
        print ("})")
    print ("")
print ("return r")
print ("}")
