// Copyright (C) 2015 The Android Open Source Project
//
// 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.

package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

const indent = "  "

// Generate the "gles.api" file from combined online and hand written data.
func GenerateApi(reg *Registry, api KhronosAPI) {
	files := map[string]*os.File{}
	printEnums(createFile(files, "glenum"), reg, api, false)
	printEnums(createFile(files, "glbitfield"), reg, api, true)
	for _, cmd := range reg.Command {
		versions := reg.GetVersions(api, cmd.Name())
		extensions := reg.GetExtensions(api, cmd.Name())
		if versions != nil {
			printCommand(createFile(files, getCategory(cmd.Name())), reg, &cmd, api)
		}
		if extensions != nil {
			if isInAndroidExtensionPack(extensions) {
				printCommand(createFile(files, "android_extension_pack"), reg, &cmd, api)
			} else {
				printCommand(createFile(files, "extensions"), reg, &cmd, api)
			}
		}
	}
	for _, file := range files {
		if err := file.Close(); err != nil {
			panic(err)
		}
	}
}

func createFile(files map[string]*os.File, basename string) *os.File {
	filename := *apiDir + string(os.PathSeparator) + basename + ".api"
	if file, ok := files[filename]; ok {
		return file
	}
	file, err := os.Create(filename)
	if err != nil {
		panic(err)
	}
	files[filename] = file
	fmt.Fprint(file, `// Copyright (C) 2015 The Android Open Source Project
//
// 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.

`)
	return file
}

func getCategory(cmdName string) string {
	var table = []struct {
		category string
		cmdName  string // Regexp
	}{
		{"asynchronous_queries", ".*(Query|Queries).*"},
		{"synchronization", ".*Sync.*"},
		{"programs_and_shaders", ".*(Program|Shader|Compute|Uniform|MemoryBarrier|GetFragDataLocation|glValidateProgram|AttribLocation|GetActiveAttrib).*"},
		{"framebuffer", ".*(Framebuffer|Renderbuffer).*|glReadBuffer|glReadPixels|gl(Color|Depth|Stencil)Mask|glClear.*|glInvalidate.*"},
		{"textures_and_samplers", ".*(Tex|Image|Sampler|PixelStorei|GenerateMipmap).*"},
		{"transform_feedback", "gl(.*TransformFeedback.*)"},
		{"vertex_arrays", ".*Vertex(Attrib|Buffer|Binding|Array).*"},
		{"draw_commands", "glDraw.*"},
		{"rasterization", "gl(GetMultisamplefv|LineWidth|FrontFace|CullFace|PolygonOffset|DepthRangef|Viewport)"},
		{"fragment_operations", "glScissor|glSample.*|glStencil.*|glDepthFunc|glBlend.*"},
		{"state_queries", "gl(GetBoolean|GetInteger|GetFloat|IsEnabled|GetString|GetInternalformativ).*"},
		{"other", "glEnable|glDisable|glIsEnabled|glHint|glGetError|glFlush|glFinish"},
		{"buffer_objects", ".*Buffer.*"},
	}
	for _, row := range table {
		if CompileRegexp("^(?:" + row.cmdName + ")").MatchString(cmdName) {
			return row.category
		}
	}
	panic(fmt.Errorf("Can not find category of %v", cmdName))
}

func isInAndroidExtensionPack(extensions []string) (result bool) {
	aep := map[string]bool{
		"GL_KHR_debug":                                true,
		"GL_KHR_texture_compression_astc_ldr":         true,
		"GL_KHR_blend_equation_advanced":              true,
		"GL_OES_sample_shading":                       true,
		"GL_OES_sample_variables":                     true,
		"GL_OES_shader_image_atomic":                  true,
		"GL_OES_shader_multisample_interpolation":     true,
		"GL_OES_texture_stencil8":                     true,
		"GL_OES_texture_storage_multisample_2d_array": true,
		"GL_EXT_copy_image":                           true,
		"GL_EXT_draw_buffers_indexed":                 true,
		"GL_EXT_geometry_shader":                      true,
		"GL_EXT_gpu_shader5":                          true,
		"GL_EXT_primitive_bounding_box":               true,
		"GL_EXT_shader_io_blocks":                     true,
		"GL_EXT_tessellation_shader":                  true,
		"GL_EXT_texture_border_clamp":                 true,
		"GL_EXT_texture_buffer":                       true,
		"GL_EXT_texture_cube_map_array":               true,
		"GL_EXT_texture_sRGB_decode":                  true,
	}
	for _, extension := range extensions {
		if aep[extension] {
			return true
		}
	}
	return false
}

func wrap(text string, width int, linePrefix string) string {
	if len(text) > width {
		if idx := strings.LastIndex(text[0:width], " "); idx != -1 {
			return text[0:idx] + "\n" + wrap(linePrefix+text[idx+1:], width, linePrefix)
		}
	}
	return text
}

func printEnums(out io.Writer, r *Registry, api KhronosAPI, bitfields bool) {
	if bitfields {
		fmt.Fprintf(out, "bitfield GLbitfield {\n")
	} else {
		fmt.Fprintf(out, "enum GLenum {\n")
	}
	for _, enums := range r.Enums {
		if (enums.Type == "bitmask") == bitfields && enums.Namespace == "GL" && len(enums.Enum) > 0 {
			for _, enum := range enums.Enum {
				// The following 64bit values are not proper GLenum values.
				if enum.Name == "GL_TIMEOUT_IGNORED" || enum.Name == "GL_TIMEOUT_IGNORED_APPLE" {
					continue
				}
				if enum.API == "" || enum.API == api {
					var value uint32
					if v, err := strconv.ParseUint(enum.Value, 0, 32); err == nil {
						value = uint32(v)
					} else if v, err := strconv.ParseInt(enum.Value, 0, 32); err == nil {
						value = uint32(v)
					} else {
						panic(fmt.Errorf("Failed to parse enum value %v", enum.Value))
					}
					fmt.Fprintf(out, indent+"%-64s = 0x%08X,\n", enum.Name, value)
				}
			}
		}
	}
	fmt.Fprintf(out, "}\n\n")
}

func renameType(cmdName string, paramIndex int, paramType, paramName string) string {
	if paramType == "const void *" {
		if oldType, ok := oldParamType(cmdName, paramIndex); ok {
			if strings.Contains(oldType, "Pointer") {
				return oldType
			}
		}
	}
	if paramType == "const GLchar *" {
		if oldType, ok := oldParamType(cmdName, paramIndex); ok {
			if oldType == "string" {
				return oldType
			}
		}
	}

	// Find the root GL type, ignoring any prefix or sufix
	loc := CompileRegexp(`\bGL\w+\b`).FindStringIndex(paramType)
	if loc == nil {
		return paramType
	}
	glType := paramType[loc[0]:loc[1]]

	// Type substitution table
	table := []struct {
		oldType   string
		cmdName   string // regexp
		paramName string // regexp
		newType   string
	}{
		{"GLboolean", "glIs.*", "result", "bool"},
		{"GLint", ".*Uniform.*", "location|result", "UniformLocation"},
		{"GLuint", ".*", "program(|s)", "ProgramId"},
		{"GLuint", ".*", "texture(|s)", "TextureId"},
		{"GLuint", ".*", "uniformBlockIndex", "UniformBlockId"},
		{"GLuint", ".*(Query|Queries).*", "id(|s)", "QueryId"},
		{"GLuint", ".*Buffer.*", "buffer(|s)", "BufferId"},
		{"GLuint", ".*Framebuffer.*", "framebuffer(|s)", "FramebufferId"},
		{"GLuint", ".*Program.*", "pipeline(|s)", "PipelineId"},
		{"GLuint", ".*Renderbuffer.*", "renderbuffer(|s)", "RenderbufferId"},
		{"GLuint", ".*Sampler.*", "sampler(|s)", "SamplerId"},
		{"GLuint", ".*Shader.*", "shader(|s)", "ShaderId"},
		{"GLuint", ".*TransformFeedback.*", "id(|s)", "TransformFeedbackId"},
		{"GLuint", ".*VertexArray.*", "array(|s)", "VertexArrayId"},
		{"GLuint", "glCreateProgram", "result", "ProgramId"},
		{"GLuint", "glCreateShader", "result", "ShaderId"},
		{"GLuint", "glCreateShaderProgramv", "result", "ProgramId"},
		{"GLuint", "glGetUniformBlockIndex", "result", "UniformBlockId"},
		{"GLuint", ".*Attrib.*", "result|index", "AttributeLocation"},
	}
	for _, row := range table {
		if row.oldType == glType &&
			CompileRegexp("^(?:"+row.paramName+")$").MatchString(paramName) &&
			CompileRegexp("^(?:"+row.cmdName+")$").MatchString(cmdName) {
			// Replacte the GL type, but keep the original prefix and sufix
			return paramType[:loc[0]] + row.newType + paramType[loc[1]:]
		}
	}
	return paramType
}

func printChecks(out io.Writer, cmd *Command, versions []Version) {
	if versions == nil {
		return
	}
	fmt.Fprintf(out, indent+"minRequiredVersion(%v)\n", strings.Replace(string(versions[0]), ".", ", ", -1))
	for paramIndex, param := range cmd.Param {
		paramName := oldParamName(cmd.Name(), paramIndex, param.Name)
		if param.Type() == "GLenum" {
			fmt.Fprintf(out, indent+"switch (%s) {\n", paramName)
			seen := map[string]Version{}
			for _, version := range versions {
				doc := DownloadDoc(version, cmd.Name())
				var newCases []string
				for _, value := range doc.Params[paramIndex].Accepts {
					if _, ok := seen[value]; !ok {
						newCases = append(newCases, value)
					}
					seen[value] = version
				}
				// Check that the set of accepted values is increasing from verions to version.
				for k, v := range seen {
					if v != version {
						fmt.Fprintf(out, indent+indent+"// TODO: %s seems to be removed in %v\n", k, version)
					}
				}
				if newCases != nil {
					line := fmt.Sprintf(indent+indent+"case %s: {\n", strings.Join(newCases, ", "))
					fmt.Fprint(out, wrap(line, 100, indent+indent+indent+indent))
					if version != versions[0] {
						fmt.Fprintf(out, indent+indent+indent+"minRequiredVersion(%v)\n", strings.Replace(string(version), ".", ", ", -1))
					} else {
						fmt.Fprintf(out, indent+indent+indent+"// version %v\n", version)
					}
					fmt.Fprint(out, indent+indent+"}\n")
				}
			}
			fmt.Fprint(out, indent+indent+"default: {\n")
			fmt.Fprintf(out, indent+indent+indent+"glErrorInvalidEnum(%s)\n", paramName)
			fmt.Fprint(out, indent+indent+"}\n")
			fmt.Fprintf(out, indent+"}\n")
		}
		if param.Type() == "GLbitfield" {
			bits := []string{}
			seen := map[string]Version{} // name -> min_version
			for _, version := range versions {
				doc := DownloadDoc(version, cmd.Name())
				for _, value := range doc.Params[paramIndex].Accepts {
					if _, ok := seen[value]; !ok {
						bits = append(bits, value)
						seen[value] = version
					}
				}
			}
			if len(bits) > 0 {
				fmt.Fprintf(out, indent+"supportsBits(%s, %s)\n", paramName, strings.Join(bits, "|"))
				for _, bit := range bits {
					version := seen[bit]
					fmt.Fprintf(out, indent+"if (%s in %s) {\n", bit, paramName)
					if version != versions[0] {
						fmt.Fprintf(out, indent+indent+"minRequiredVersion(%v)\n", strings.Replace(string(version), ".", ", ", -1))
					}
					fmt.Fprintf(out, indent+"}\n")
				}
			}
		}
	}
}

func printCommand(out io.Writer, reg *Registry, cmd *Command, api KhronosAPI) {
	versions := reg.GetVersions(api, cmd.Name())
	extensions := reg.GetExtensions(api, cmd.Name())
	if versions != nil && extensions != nil {
		panic(fmt.Errorf("%s is both core feature and extension", cmd.Name()))
	}

	// Print comments
	for _, version := range versions {
		url, _, _, _ := GetDocUrl(version, cmd.Name())
		fmt.Fprintf(out, `@Doc("%s","OpenGL ES %v")`+"\n", url, version)
	}
	for _, extension := range extensions {
		url := GetExtensionUrl(extension)
		fmt.Fprintf(out, `@Doc("%s","%v")`+"\n", url, extension)
	}

	// Print function signature
	sig := &bytes.Buffer{}
	fmt.Fprintf(sig, "cmd %s %s(", renameType(cmd.Name(), -1, cmd.Proto.Type(), "result"), cmd.Name())
	leadWidth := sig.Len()
	maxTypeWidth := 0
	paramTypes := []string{}
	for paramIndex, param := range cmd.Param {
		paramType := renameType(cmd.Name(), paramIndex, param.Type(), param.Name)
		paramTypes = append(paramTypes, paramType)
		if typeWidth := len(paramType); typeWidth > maxTypeWidth {
			maxTypeWidth = typeWidth
		}
	}
	for i, param := range cmd.Param {
		if i > 0 {
			fmt.Fprintf(sig, ",\n%s", strings.Repeat(" ", leadWidth))
		}
		format := fmt.Sprintf("%%-%vs %%s", maxTypeWidth)
		fmt.Fprintf(sig, format, paramTypes[i], oldParamName(cmd.Name(), i, param.Name))
		if oldType, ok := oldParamType(cmd.Name(), i); ok {
			newType := strings.Replace(paramTypes[i], " *", "*", -1)
			if newType != oldType {
				// fmt.Printf("Changed type of %s:%s from %s to %s\n", cmd.Name(), param.Name, oldType, newType)
			}
		}
	}
	fmt.Fprintf(sig, ")")
	longSig := string(sig.Bytes())
	shortSig := CompileRegexp(`\s+`).ReplaceAllString(longSig, " ")
	if len(shortSig)+2 <= 100 {
		fmt.Fprintf(out, "%s ", shortSig)
	} else {
		fmt.Fprintf(out, "%s ", longSig)
	}

	// Print function body
	fmt.Fprintf(out, "{\n")
	for _, extension := range extensions {
		fmt.Fprintf(out, indent+"requiresExtension(%s)\n", extension)
	}
	if len(extensions) > 1 {
		fmt.Fprintf(out, indent+"// TODO: Multiple extensions\n")
	}
	printChecks(out, cmd, versions)
	foundOldCode := false
	if oldApi != nil {
		// Try to add the old code
		for _, apiCmd := range oldApi.Commands {
			if apiCmd.Name.Value == cmd.Name() {
				childs := apiCmd.Block.CST.Children
				if len(childs) > 0 {
					start := apiCmd.Block.CST.Children[0].Token()
					end := apiCmd.Block.CST.Children[len(childs)-1].Token()
					fmt.Fprintf(out, "%s", string(start.Source.Runes[start.End:end.Start]))
					foundOldCode = true
				}
			}
		}
	}
	if !foundOldCode {
		fmt.Fprintf(out, indent+"// TODO\n")
		if cmd.Proto.Type() != "void" {
			fmt.Fprint(out, indent+"return ?\n")
		}
	}
	fmt.Fprintf(out, "}\n")
	fmt.Fprintf(out, "\n")
}

// Rename parameters so that they match our old api file
func oldParamName(cmdName string, paramIndex int, paramName string) string {
	if oldApi != nil {
		for _, cmd := range oldApi.Commands {
			if cmd.Name.Value == cmdName {
				return cmd.Parameters[paramIndex].Name.Value
			}
		}
	}
	return paramName
}

func oldParamType(cmdName string, paramIndex int) (string, bool) {
	if oldApi != nil {
		for _, cmd := range oldApi.Commands {
			if cmd.Name.Value == cmdName {
				token := cmd.Parameters[paramIndex].Type.Node().Token()
				return string(token.Source.Runes[token.Start:token.End]), true
			}
		}
	}
	return "", false
}
