// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"go/format"
	"io"
	"log"
	"os"
	"text/template"
)

func main() {
	log.SetFlags(0)
	if err := run(os.Args[1:]); err != nil {
		log.Fatalf("%+v", err)
	}
}

func run(args []string) error {
	var opts struct {
		Name string
		Type string
		Zero string
		File string
	}

	flag := flag.NewFlagSet("gen-atomicint", flag.ContinueOnError)

	flag.StringVar(&opts.Name, "name", "", "name of the generated type (e.g. Int32)")
	flag.StringVar(&opts.Type, "type", "", "name of the wrapped type (e.g. int32)")
	flag.StringVar(&opts.Zero, "zero", "", "zero value of the wrapped type (e.g. nil)")
	flag.StringVar(&opts.File, "file", "", "output file path (default: stdout)")

	if err := flag.Parse(args); err != nil {
		return err
	}

	if len(opts.Name) == 0 || len(opts.Type) == 0 || len(opts.Zero) == 0 {
		return errors.New("flags -name, -type, and -zero are required")
	}

	var w io.Writer = os.Stdout
	if file := opts.File; len(file) > 0 {
		f, err := os.Create(file)
		if err != nil {
			return fmt.Errorf("create %q: %v", file, err)
		}
		defer f.Close()

		w = f
	}

	data := struct {
		Name     string
		Type     string
		Zero     string
		Nillable bool
	}{
		Name:     opts.Name,
		Type:     opts.Type,
		Zero:     opts.Zero,
		Nillable: opts.Zero == "nil",
	}

	var buff bytes.Buffer
	if err := _tmpl.Execute(&buff, data); err != nil {
		return fmt.Errorf("render template: %v", err)
	}

	bs, err := format.Source(buff.Bytes())
	if err != nil {
		return fmt.Errorf("reformat source: %v", err)
	}

	_, err = w.Write(bs)
	return err
}

var _tmpl = template.Must(template.New("int.go").Parse(`// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package atomic

// {{ .Name }} is an atomic type-safe wrapper for {{ .Type }} values.
type {{ .Name }} struct{ v Value }

{{/* atomic.Value panics for nil values. Generate a wrapper for these types. */}}
{{ $stored := .Type }}
{{ $wrap := .Type }}
{{ $unwrap := .Type }}
{{ if .Nillable -}}
	{{ $stored = printf "stored%s" .Name }}
	{{ $wrap = printf "wrap%s" .Name }}
	{{ $unwrap = printf "unwrap%s" .Name }}

	type {{ $stored }} struct{ Value {{ .Type }} }

	func {{ $wrap }}(v {{ .Type }}) {{ $stored }} {
		return {{ $stored }}{v}
	}

	func {{ $unwrap }}(v {{ $stored }}) {{ .Type }} {
		return v.Value
	}
{{- end }}

// New{{ .Name }} creates a new {{ .Name }}.
func New{{ .Name }}(v {{ .Type }}) *{{ .Name }} {
	x := &{{ .Name }}{}
	if v != {{ .Zero }} {
		x.Store(v)
	}
	return x
}

// Load atomically loads the wrapped {{ .Type }}.
func (x *{{ .Name }}) Load() {{ .Type }} {
	v := x.v.Load()
	if v == nil {
		return {{ .Zero }}
	}
	return {{ $unwrap }}(v.({{ $stored }}))
}

// Store atomically stores the passed {{ .Type }}.
//
// NOTE: This will cause an allocation.
func (x *{{ .Name }}) Store(v {{ .Type }}) {
	x.v.Store({{ $wrap }}(v))
}
`))
