// Copyright 2017 Google 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.

// generator generates Protocol Buffer models and support code from
// JSON Schemas. It is used to generate representations of the
// OpenAPI Specification and vendor and specification extensions
// that are added by third-party OpenAPI authors.
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"runtime"
	"strings"

	"github.com/googleapis/gnostic/jsonschema"
)

// License is the software license applied to generated code.
const License = "" +
	"// Copyright 2017 Google Inc. All Rights Reserved.\n" +
	"//\n" +
	"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" +
	"// you may not use this file except in compliance with the License.\n" +
	"// You may obtain a copy of the License at\n" +
	"//\n" +
	"//    http://www.apache.org/licenses/LICENSE-2.0\n" +
	"//\n" +
	"// Unless required by applicable law or agreed to in writing, software\n" +
	"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
	"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
	"// See the License for the specific language governing permissions and\n" +
	"// limitations under the License.\n"

func protoOptions(packageName string) []ProtoOption {
	return []ProtoOption{
		ProtoOption{
			Name:  "java_multiple_files",
			Value: "true",
			Comment: "// This option lets the proto compiler generate Java code inside the package\n" +
				"// name (see below) instead of inside an outer class. It creates a simpler\n" +
				"// developer experience by reducing one-level of name nesting and be\n" +
				"// consistent with most programming languages that don't support outer classes.",
		},

		ProtoOption{
			Name:  "java_outer_classname",
			Value: "OpenAPIProto",
			Comment: "// The Java outer classname should be the filename in UpperCamelCase. This\n" +
				"// class is only used to hold proto descriptor, so developers don't need to\n" +
				"// work with it directly.",
		},

		ProtoOption{
			Name:    "java_package",
			Value:   "org." + packageName,
			Comment: "// The Java package name must be proto package name with proper prefix.",
		},

		ProtoOption{
			Name:  "objc_class_prefix",
			Value: "OAS",
			Comment: "// A reasonable prefix for the Objective-C symbols generated from the package.\n" +
				"// It should at a minimum be 3 characters long, all uppercase, and convention\n" +
				"// is to use an abbreviation of the package name. Something short, but\n" +
				"// hopefully unique enough to not conflict with things that may come along in\n" +
				"// the future. 'GPB' is reserved for the protocol buffer implementation itself.",
		},
	}
}

func generateOpenAPIModel(version string) error {
	var input string
	var filename string
	var protoPackageName string

	switch version {
	case "v2":
		input = "openapi-2.0.json"
		filename = "OpenAPIv2"
		protoPackageName = "openapi.v2"
	case "v3":
		input = "openapi-3.0.json"
		filename = "OpenAPIv3"
		protoPackageName = "openapi.v3"
	case "discovery":
		input = "discovery.json"
		filename = "discovery"
		protoPackageName = "discovery.v1"
	default:
		return fmt.Errorf("Unknown OpenAPI version %s", version)
	}

	goPackageName := strings.Replace(protoPackageName, ".", "_", -1)

	projectRoot := os.Getenv("GOPATH") + "/src/github.com/googleapis/gnostic/"

	baseSchema, err := jsonschema.NewSchemaFromFile(projectRoot + "jsonschema/schema.json")
	if err != nil {
		return err
	}
	baseSchema.ResolveRefs()
	baseSchema.ResolveAllOfs()

	openapiSchema, err := jsonschema.NewSchemaFromFile(projectRoot + filename + "/" + input)
	if err != nil {
		return err
	}
	openapiSchema.ResolveRefs()
	openapiSchema.ResolveAllOfs()

	// build a simplified model of the types described by the schema
	cc := NewDomain(openapiSchema, version)
	// generators will map these patterns to the associated property names
	// these pattern names are a bit of a hack until we find a more automated way to obtain them

	switch version {
	case "v2":
		cc.TypeNameOverrides = map[string]string{
			"VendorExtension": "Any",
		}
		cc.PropertyNameOverrides = map[string]string{
			"PathItem":      "Path",
			"ResponseValue": "ResponseCode",
		}
	case "v3":
		cc.TypeNameOverrides = map[string]string{
			"SpecificationExtension": "Any",
		}
		cc.PropertyNameOverrides = map[string]string{
			"PathItem":      "Path",
			"ResponseValue": "ResponseCode",
		}
	case "discovery":
		cc.TypeNameOverrides = map[string]string{}
		cc.PropertyNameOverrides = map[string]string{}
	default:
		return fmt.Errorf("Unknown OpenAPI version %s", version)
	}

	err = cc.Build()
	if err != nil {
		return err
	}

	if true {
		log.Printf("Type Model:\n%s", cc.Description())
	}

	// ensure that the target directory exists
	err = os.MkdirAll(projectRoot+filename, 0755)
	if err != nil {
		return err
	}

	// generate the protocol buffer description
	log.Printf("Generating protocol buffer description")
	proto := cc.generateProto(protoPackageName, License,
		protoOptions(goPackageName), []string{"google/protobuf/any.proto"})
	protoFileName := projectRoot + filename + "/" + filename + ".proto"
	err = ioutil.WriteFile(protoFileName, []byte(proto), 0644)
	if err != nil {
		return err
	}

	// generate the compiler
	log.Printf("Generating compiler support code")
	compiler := cc.GenerateCompiler(goPackageName, License, []string{
		"fmt",
		"gopkg.in/yaml.v2",
		"strings",
		"regexp",
		"github.com/googleapis/gnostic/compiler",
	})
	goFileName := projectRoot + filename + "/" + filename + ".go"
	err = ioutil.WriteFile(goFileName, []byte(compiler), 0644)
	if err != nil {
		return err
	}
	// format the compiler
	log.Printf("Formatting compiler support code")
	return exec.Command(runtime.GOROOT()+"/bin/gofmt", "-w", goFileName).Run()
}

func usage() string {
	return fmt.Sprintf(`
Usage: %s [OPTIONS]
Options:
  --v2
    Generate Protocol Buffer representation and support code for OpenAPI v2.
    Files are read from and written to appropriate locations in the gnostic
    project directory.
  --v3
    Generate Protocol Buffer representation and support code for OpenAPI v3
    Files are read from and written to appropriate locations in the gnostic
    project directory.
  --extension EXTENSION_SCHEMA [EXTENSIONOPTIONS]
    Generate a gnostic extension that reads a set of OpenAPI extensions.
    EXTENSION_SCHEMA is the json schema for the OpenAPI extensions to be
    supported.
    EXTENSION_OPTIONS
      --out_dir=PATH: Location for writing extension models and support code.
`, path.Base(os.Args[0]))
}

func main() {
	var openapiVersion = ""
	var generateExtensions = false

	for i, arg := range os.Args {
		if i == 0 {
			continue // skip the tool name
		}
		if arg == "--v2" {
			openapiVersion = "v2"
		} else if arg == "--v3" {
			openapiVersion = "v3"
		} else if arg == "--discovery" {
			openapiVersion = "discovery"
		} else if arg == "--extension" {
			generateExtensions = true
			break
		} else {
			fmt.Printf("Unknown option: %s.\n%s\n", arg, usage())
			os.Exit(-1)
		}
	}

	if openapiVersion != "" {
		err := generateOpenAPIModel(openapiVersion)
		if err != nil {
			fmt.Printf("%+v\n", err)
		}
	} else if generateExtensions {
		err := processExtensionGenCommandline(usage())
		if err != nil {
			fmt.Printf("%+v\n", err)
		}
	} else {
		fmt.Printf("%s\n", usage())
	}
}
