// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains examples to embed in the Go 1 release notes document.

package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"testing"
	"time"
	"unicode"
)

func main() {
	flag.Parse()
	stringAppend()
	mapDelete()
	mapIteration()
	multipleAssignment()
	structEquality()
	compositeLiterals()
	runeType()
	errorExample()
	timePackage()
}

var timeout = flag.Duration("timeout", 30*time.Second, "how long to wait for completion")

func mapDelete() {
	m := map[string]int{"7": 7, "23": 23}
	k := "7"
	delete(m, k)
	if m["7"] != 0 || m["23"] != 23 {
		log.Fatal("mapDelete:", m)
	}
}

func stringAppend() {
	greeting := []byte{}
	greeting = append(greeting, []byte("hello ")...)
	greeting = append(greeting, "world"...)
	if string(greeting) != "hello world" {
		log.Fatal("stringAppend: ", string(greeting))
	}
}

func mapIteration() {
	m := map[string]int{"Sunday": 0, "Monday": 1}
	for name, value := range m {
		// This loop should not assume Sunday will be visited first.
		f(name, value)
	}
}

func f(string, int) {
}

func assert(t bool) {
	if !t {
		log.Panic("assertion fail")
	}
}

func multipleAssignment() {
	sa := []int{1, 2, 3}
	i := 0
	i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2

	sb := []int{1, 2, 3}
	j := 0
	sb[j], j = 2, 1 // sets sb[0] = 2, j = 1

	sc := []int{1, 2, 3}
	sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)

	assert(i == 1 && sa[0] == 2)
	assert(j == 1 && sb[0] == 2)
	assert(sc[0] == 2)
}

func structEquality() {
	type Day struct {
		long  string
		short string
	}
	Christmas := Day{"Christmas", "XMas"}
	Thanksgiving := Day{"Thanksgiving", "Turkey"}
	holiday := map[Day]bool{
		Christmas:    true,
		Thanksgiving: true,
	}
	fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
}

func compositeLiterals() {
	type Date struct {
		month string
		day   int
	}
	// Struct values, fully qualified; always legal.
	holiday1 := []Date{
		Date{"Feb", 14},
		Date{"Nov", 11},
		Date{"Dec", 25},
	}
	// Struct values, type name elided; always legal.
	holiday2 := []Date{
		{"Feb", 14},
		{"Nov", 11},
		{"Dec", 25},
	}
	// Pointers, fully qualified, always legal.
	holiday3 := []*Date{
		&Date{"Feb", 14},
		&Date{"Nov", 11},
		&Date{"Dec", 25},
	}
	// Pointers, type name elided; legal in Go 1.
	holiday4 := []*Date{
		{"Feb", 14},
		{"Nov", 11},
		{"Dec", 25},
	}
	// STOP OMIT
	_, _, _, _ = holiday1, holiday2, holiday3, holiday4
}

func runeType() {
	// STARTRUNE OMIT
	delta := 'δ' // delta has type rune.
	var DELTA rune
	DELTA = unicode.ToUpper(delta)
	epsilon := unicode.ToLower(DELTA + 1)
	if epsilon != 'δ'+1 {
		log.Fatal("inconsistent casing for Greek")
	}
	// ENDRUNE OMIT
}

// START ERROR EXAMPLE OMIT
type SyntaxError struct {
	File    string
	Line    int
	Message string
}

func (se *SyntaxError) Error() string {
	return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
}

// END ERROR EXAMPLE OMIT

func errorExample() {
	var ErrSyntax = errors.New("syntax error")
	_ = ErrSyntax
	se := &SyntaxError{"file", 7, "error"}
	got := fmt.Sprint(se)
	const expect = "file:7: error"
	if got != expect {
		log.Fatalf("errorsPackage: expected %q got %q", expect, got)
	}
}

// sleepUntil sleeps until the specified time. It returns immediately if it's too late.
func sleepUntil(wakeup time.Time) {
	now := time.Now() // A Time.
	if !wakeup.After(now) {
		return
	}
	delta := wakeup.Sub(now) // A Duration.
	log.Printf("Sleeping for %.3fs", delta.Seconds())
	time.Sleep(delta)
}

func timePackage() {
	sleepUntil(time.Now().Add(123 * time.Millisecond))
}

func initializationFunction(c chan int) {
	c <- 1
}

var PackageGlobal int

func init() {
	c := make(chan int)
	go initializationFunction(c)
	PackageGlobal = <-c
}

func BenchmarkSprintf(b *testing.B) {
	// Verify correctness before running benchmark.
	b.StopTimer()
	got := fmt.Sprintf("%x", 23)
	const expect = "17"
	if expect != got {
		b.Fatalf("expected %q; got %q", expect, got)
	}
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		fmt.Sprintf("%x", 23)
	}
}
