// Copyright 2018 The Wuffs Authors.
//
// 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
//
//    https://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"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"time"

	cf "github.com/google/wuffs/cmd/commonflags"
)

func doGenrelease(args []string) error {
	flags := flag.FlagSet{}
	cformatterFlag := flags.String("cformatter", cf.CformatterDefault, cf.CformatterUsage)
	revisionFlag := flags.String("revision", "", "git revision the release was built from")
	versionFlag := flags.String("version", cf.VersionDefault, cf.VersionUsage)

	if err := flags.Parse(args); err != nil {
		return err
	}
	if !cf.IsAlphaNumericIsh(*cformatterFlag) {
		return fmt.Errorf("bad -cformatter flag value %q", *cformatterFlag)
	}
	if !cf.IsAlphaNumericIsh(*revisionFlag) {
		return fmt.Errorf("bad -revision flag value %q", *revisionFlag)
	}
	v, ok := cf.ParseVersion(*versionFlag)
	if !ok {
		return fmt.Errorf("bad -version flag value %q", *versionFlag)
	}
	args = flags.Args()

	h := &genReleaseHelper{
		seen:     map[string]bool{},
		revision: *revisionFlag,
		version:  v,
	}

	unformatted := bytes.NewBuffer(nil)
	unformatted.WriteString("#ifndef WUFFS_INCLUDE_GUARD\n")
	unformatted.WriteString("#define WUFFS_INCLUDE_GUARD\n\n")

	// First, cat all of the headers together, filtering out duplicate
	// WUFFS_INCLUDE_GUARD__FOO sections and overriding WUFFS_VERSION.
	for _, filename := range args {
		s, err := ioutil.ReadFile(filename)
		if err != nil {
			return err
		}

		if i := bytes.Index(s, grCHeader); i >= 0 {
			s = s[:i]
		} else {
			return fmt.Errorf("could not find %q", grCHeader)
		}

		if err := h.gen(unformatted, s); err != nil {
			return fmt.Errorf("%v in %s", err, filename)
		}
	}

	unformatted.WriteString("\n\n#endif  // WUFFS_INCLUDE_GUARD\n\n")
	unformatted.Write(grCHeader)
	unformatted.WriteString("\n")

	// Then, cat all of the implementations together, filtering out duplicate
	// WUFFS_INCLUDE_GUARD__BASE_PRIVATE sections.
	for _, filename := range args {
		s, err := ioutil.ReadFile(filename)
		if err != nil {
			return err
		}

		if i := bytes.Index(s, grCHeader); i >= 0 {
			s = s[i+len(grCHeader):]
		} else {
			continue
		}

		if err := h.gen(unformatted, s); err != nil {
			return fmt.Errorf("%v in %s", err, filename)
		}
	}

	cmd := exec.Command(*cformatterFlag, "-style=Chromium")
	cmd.Stdin = unformatted
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

var (
	grCHeader   = []byte("// !! C HEADER ENDS HERE.\n")
	grNN        = []byte("\n\n")
	grVOverride = []byte("// !! Some code generation programs can override WUFFS_VERSION.\n")
	grVString   = []byte(`#define WUFFS_VERSION_STRING "0.0.0"`)

	grDefine = []byte("#define WUFFS_INCLUDE_GUARD__")
	grEndif  = []byte("#endif  // WUFFS_INCLUDE_GUARD__")
	grIfndef = []byte("#ifndef WUFFS_INCLUDE_GUARD__")
)

type genReleaseHelper struct {
	seen     map[string]bool
	revision string
	version  cf.Version
}

func (h *genReleaseHelper) gen(w *bytes.Buffer, s []byte) error {
	skipping := 0
	stack := []string{}

	for remaining := []byte(nil); len(s) > 0; s, remaining = remaining, nil {
		if i := bytes.IndexByte(s, '\n'); i >= 0 {
			s, remaining = s[:i+1], s[i+1:]
		}
		if len(s) == 0 {
			continue
		}

		if s[0] == '#' {
			switch {
			case bytes.HasPrefix(s, grIfndef):
				pkg := string(s[len(grIfndef):])
				for _, p := range stack {
					if p == pkg {
						return fmt.Errorf("unexpected %q", s)
					}
				}

				if h.seen[pkg] {
					skipping++
				}

				stack = append(stack, pkg)
				continue

			case bytes.HasPrefix(s, grDefine):
				pkg := string(s[len(grDefine):])
				if (len(stack) == 0) || (stack[len(stack)-1] != pkg) {
					return fmt.Errorf("unexpected %q", s)
				}
				continue

			case bytes.HasPrefix(s, grEndif):
				pkg := string(s[len(grEndif):])
				if (len(stack) == 0) || (stack[len(stack)-1] != pkg) {
					return fmt.Errorf("unexpected %q", s)
				}

				if h.seen[pkg] {
					skipping--
				} else {
					h.seen[pkg] = true
				}

				stack = stack[:len(stack)-1]
				continue
			}
		}

		if skipping > 0 {
			continue
		}

		if s[0] == '/' {
			switch {
			case bytes.Equal(s, grVOverride):
				var err error
				remaining, err = h.genWuffsVersion(w, remaining)
				if err != nil {
					return err
				}
				continue
			}
		}

		w.Write(s)
	}

	if len(stack) != 0 {
		return fmt.Errorf("unmatched %q", string(grIfndef)+stack[len(stack)-1])
	}
	return nil
}

func (h *genReleaseHelper) genWuffsVersion(w *bytes.Buffer, s []byte) (remaining []byte, err error) {
	cut := []byte(nil)
	if i := bytes.Index(s, grNN); i >= 0 {
		cut, s = s[:i], s[i+len(grNN):]
	} else {
		return nil, fmt.Errorf(`could not find "\n\n" near WUFFS_VERSION`)
	}

	if !bytes.HasSuffix(cut, grVString) {
		return nil, fmt.Errorf("%q did not end with %q", cut, grVString)
	}

	fmt.Fprintf(w, "// WUFFS_VERSION was overridden by \"wuffs genrelease\" on %v UTC",
		time.Now().UTC().Format("2006-01-02"))
	if h.revision != "" {
		fmt.Fprintf(w, ",\n// based on revision %s", h.revision)
	}

	fmt.Fprintf(w, `.
		#define WUFFS_VERSION ((uint64_t)0x%016X)
		#define WUFFS_VERSION_MAJOR ((uint64_t)0x%08X)
		#define WUFFS_VERSION_MINOR ((uint64_t)0x%04X)
		#define WUFFS_VERSION_PATCH ((uint64_t)0x%04X)
		#define WUFFS_VERSION_EXTENSION %q
		#define WUFFS_VERSION_STRING %q

	`, h.version.Uint64(), h.version.Major, h.version.Minor, h.version.Patch,
		h.version.Extension, h.version)

	return s, nil
}
