// 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"
	"os"
	"path/filepath"
	"testing"
	"time"
	"unicode"
)

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

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

func init() {
	// canonicalize the logging
	log.SetFlags(0)
}

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() {
	l            // 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.
	fmt.Printf("Sleeping for %.3fs\n", delta.Seconds())
	time.Sleep(delta)
}

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

func walkExample() {
	// STARTWALK OMIT
	markFn := func(path string, info os.FileInfo, err error) error {
		if path == "pictures" { // Will skip walking of directory pictures and its contents.
			return filepath.SkipDir
		}
		if err != nil {
			return err
		}
		log.Println(path)
		return nil
	}
	err := filepath.Walk(".", markFn)
	if err != nil {
		log.Fatal(err)
	}
	// ENDWALK OMIT
}

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)
	}
}

func osIsExist() {
	name := "go1.go"
	f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
	if os.IsExist(err) {
		log.Printf("%s already exists", name)
	}
	_ = f
}

func closeExample() {
	// STARTCLOSE OMIT
	var c chan int
	var csend chan<- int = c
	var crecv <-chan int = c
	close(c)     // legal
	close(csend) // legal
	close(crecv) // illegal
	// ENDCLOSE OMIT
}

func Bug() (i, j, k int) {
	for i = 0; i < 5; i++ {
		for j := 0; j < 5; j++ { // Redeclares j.
			k += i * j
			if k > 100 {
				return // Rejected: j is shadowed here.
			}
		}
	}
	return // OK: j is not shadowed here.
}
