// Copyright 2009 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.

package imports

import "io"

import (
	_ "io"
)

import _ "io"

import (
	"io"
	"io"
	"io"
)

import (
	"io"
	aLongRename "io"

	b "io"
)

import (
       "unrenamed"
       renamed "renameMe"
       . "io"
       _ "io"
       "io"
       . "os"
)

// no newlines between consecutive single imports, but
// respect extra line breaks in the source (at most one empty line)
import _ "io"
import _ "io"
import _ "io"

import _ "os"
import _ "os"
import _ "os"


import _ "fmt"
import _ "fmt"
import _ "fmt"

import "foo"  // a comment
import "bar"  // a comment

import (
	_ "foo"
	// a comment
	"bar"
	"foo"  // a comment
	"bar"  // a comment
)

// comments + renames
import (
       "unrenamed" // a comment
       renamed "renameMe"
       . "io" /* a comment */
       _ "io/ioutil" // a comment
       "io" // testing alignment
       . "os"
       // a comment
)

// a case that caused problems in the past (comment placement)
import (
	. "fmt"
	"io"
	"malloc"	// for the malloc count test only
	"math"
	"strings"
	"testing"
)

// more import examples
import (
	"xxx"
	"much_longer_name" // comment
	"short_name" // comment
)

import (
	_ "xxx"
	"much_longer_name" // comment
)

import (
	mymath "math"
	"/foo/bar/long_package_path" // a comment
)

import (
	"package_a" // comment
	"package_b"
	my_better_c "package_c" // comment
	"package_d" // comment
	my_e "package_e" // comment

	"package_a"    // comment
	"package_bb"
	"package_ccc"  // comment
	"package_dddd" // comment
)

// at least one empty line between declarations of different kind
import _ "io"
var _ int

// at least one empty line between declarations of the same kind
// if there is associated documentation (was issue 2570)
type T1 struct{}
// T2 comment
type T2 struct {
} // should be a two-line struct


// T3 comment
type T2 struct {


} // should be a two-line struct


// printing of constant literals
const (
	_ = "foobar"
	_ = "a۰۱۸"
	_ = "foo६४"
	_ = "bar９８７６"
	_ = 0
	_ = 1
	_ = 123456789012345678890
	_ = 01234567
	_ = 0xcafebabe
	_ = 0.
	_ = .0
	_ = 3.14159265
	_ = 1e0
	_ = 1e+100
	_ = 1e-100
	_ = 2.71828e-1000
	_ = 0i
	_ = 1i
	_ = 012345678901234567889i
	_ = 123456789012345678890i
	_ = 0.i
	_ = .0i
	_ = 3.14159265i
	_ = 1e0i
	_ = 1e+100i
	_ = 1e-100i
	_ = 2.71828e-1000i
	_ = 'a'
	_ = '\000'
	_ = '\xFF'
	_ = '\uff16'
	_ = '\U0000ff16'
	_ = `foobar`
	_ = `foo
---
---
bar`
)


func _() {
	type _ int
	type _ *int
	type _ []int
	type _ map[string]int
	type _ chan int
	type _ func() int

	var _ int
	var _ *int
	var _ []int
	var _ map[string]int
	var _ chan int
	var _ func() int

	type _ struct{}
	type _ *struct{}
	type _ []struct{}
	type _ map[string]struct{}
	type _ chan struct{}
	type _ func() struct{}

	type _ interface{}
	type _ *interface{}
	type _ []interface{}
	type _ map[string]interface{}
	type _ chan interface{}
	type _ func() interface{}

	var _ struct{}
	var _ *struct{}
	var _ []struct{}
	var _ map[string]struct{}
	var _ chan struct{}
	var _ func() struct{}

	var _ interface{}
	var _ *interface{}
	var _ []interface{}
	var _ map[string]interface{}
	var _ chan interface{}
	var _ func() interface{}
}


// don't lose blank lines in grouped declarations
const (
	_ int = 0
	_ float = 1

	_ string = "foo"

	_ = iota
	_
	
	// a comment
	_

	_
)


type (
	_ int
	_ struct {}
	
	_ interface{}
	
	// a comment
	_ map[string]int
)


var (
	_ int = 0
	_ float = 1

	_ string = "foo"

	_ bool
	
	// a comment
	_ bool
)


// don't lose blank lines in this struct
type _ struct {
	String struct {
		Str, Len int
	}
	Slice struct {
		Array, Len, Cap int
	}
	Eface struct {
		Typ, Ptr int
	}

	UncommonType struct {
		Name, PkgPath int
	}
	CommonType struct {
		Size, Hash, Alg, Align, FieldAlign, String, UncommonType int
	}
	Type struct {
		Typ, Ptr int
	}
	StructField struct {
		Name, PkgPath, Typ, Tag, Offset int
	}
	StructType struct {
		Fields int
	}
	PtrType struct {
		Elem int
	}
	SliceType struct {
		Elem int
	}
	ArrayType struct {
		Elem, Len int
	}

	Stktop struct {
		Stackguard, Stackbase, Gobuf int
	}
	Gobuf struct {
		Sp, Pc, G int
	}
	G struct {
		Stackbase, Sched, Status, Alllink int
	}
}


// no blank lines in empty structs and interfaces, but leave 1- or 2-line layout alone
type _ struct{            }
type _ struct {

}

type _ interface{            }
type _ interface {

}


// no tabs for single or ungrouped decls
func _() {
	const xxxxxx = 0
	type x int
	var xxx int
	var yyyy float = 3.14
	var zzzzz = "bar"

	const (
		xxxxxx = 0
	)
	type (
		x int
	)
	var (
		xxx int
	)
	var (
		yyyy float = 3.14
	)
	var (
		zzzzz = "bar"
	)
}

// tabs for multiple or grouped decls
func _() {
	// no entry has a type
	const (
		zzzzzz = 1
		z = 2
		zzz = 3
	)
	// some entries have a type
	const (
		xxxxxx = 1
		x = 2
		xxx = 3
		yyyyyyyy float = iota
		yyyy = "bar"
		yyy
		yy = 2
	)
}

func _() {
	// no entry has a type
	var (
		zzzzzz = 1
		z = 2
		zzz = 3
	)
	// no entry has a value
	var (
		_ int
		_ float
		_ string

		_ int  // comment
		_ float  // comment
		_ string  // comment
	)
	// some entries have a type
	var (
		xxxxxx int
		x float
		xxx string
		yyyyyyyy int = 1234
		y float = 3.14
		yyyy = "bar"
		yyy string = "foo"
	)
	// mixed entries - all comments should be aligned
	var (
		a, b, c int
		x = 10
		d int  // comment
		y = 20  // comment
		f, ff, fff, ffff int = 0, 1, 2, 3  // comment
	)
	// respect original line breaks
	var _ = []T {
		T{0x20,	"Telugu"},
	}
	var _ = []T {
		// respect original line breaks
		T{0x20,	"Telugu"},
	}
}

// use the formatted output rather than the input to decide when to align
// (was issue 4505)
const (
	short = 2 * (
	1 + 2)
	aMuchLongerName = 3
)

var (
	short = X{
	}
	aMuchLongerName = X{}

	x1 = X{} // foo
	x2 = X{
	} // foo
)

func _() {
	type (
		xxxxxx int
		x float
		xxx string
		xxxxx []x
		xx struct{}
		xxxxxxx struct {
			_, _ int
			_ float
		}
		xxxx chan<- string
	)
}

// alignment of "=" in consecutive lines (extended example from issue 1414)
const (
	umax uint                  = ^uint(0) // maximum value for a uint
	bpu  = 1 << (5 + umax>>63)            // bits per uint
	foo
	bar  = -1
)

// typical enum
const (
	a MyType = iota
	abcd
	b
	c
	def
)

// excerpt from godoc.go
var (
	goroot = flag.String("goroot", runtime.GOROOT(), "Go root directory")
	testDir = flag.String("testdir", "", "Go root subdirectory - for testing only (faster startups)")
	pkgPath = flag.String("path", "", "additional package directories (colon-separated)")
	filter = flag.String("filter", "", "filter file containing permitted package directory paths")
	filterMin = flag.Int("filter_minutes", 0, "filter file update interval in minutes; disabled if <= 0")
	filterDelay delayTime // actual filter update interval in minutes; usually filterDelay == filterMin, but filterDelay may back off exponentially
)


// formatting of structs
type _ struct{}

type _ struct{ /* this comment should be visible */ }

type _ struct{
	// this comment should be visible and properly indented
}

type _ struct {  // this comment must not change indentation
	f int
	f, ff, fff, ffff int
}

type _ struct {
	string
}

type _ struct {
	string  // comment
}

type _ struct {
	string "tag"
}

type _ struct {
	string "tag"  // comment
}

type _ struct {
	f int
}

type _ struct {
	f int  // comment
}

type _ struct {
	f int "tag"
}

type _ struct {
	f int "tag"  // comment
}

type _ struct {
	bool
	a, b, c int
	int "tag"
	ES // comment
	float "tag"  // comment
	f int  // comment
	f, ff, fff, ffff int  // comment
	g float "tag"
	h float "tag"  // comment
}

type _ struct { a, b,
c, d int  // this line should be indented
u, v, w, x float // this line should be indented
p, q,
r, s float // this line should be indented
}


// difficult cases
type _ struct {
	bool  // comment
	text []byte  // comment
}


// formatting of interfaces
type EI interface{}

type _ interface {
	EI
}

type _ interface {
	f()
	fffff()
}

type _ interface {
	EI
	f()
	fffffg()
}

type _ interface {  // this comment must not change indentation
	EI  // here's a comment
	f()  // no blank between identifier and ()
	fffff()  // no blank between identifier and ()
	gggggggggggg(x, y, z int) ()  // hurray
}


// formatting of variable declarations
func _() {
	type day struct { n int; short, long string }
	var (
		Sunday = day{ 0, "SUN", "Sunday" }
		Monday = day{ 1, "MON", "Monday" }
		Tuesday = day{ 2, "TUE", "Tuesday" }
		Wednesday = day{ 3, "WED", "Wednesday" }
		Thursday = day{ 4, "THU", "Thursday" }
		Friday = day{ 5, "FRI", "Friday" }
		Saturday = day{ 6, "SAT", "Saturday" }
	)
}


// formatting of multi-line variable declarations
var a1, b1, c1 int  // all on one line

var a2, b2,
c2 int  // this line should be indented

var (a3, b3,
c3, d3 int  // this line should be indented
a4, b4, c4 int  // this line should be indented
)

// Test case from issue 3304: multi-line declarations must end
// a formatting section and not influence indentation of the
// next line.
var (
	minRefreshTimeSec = flag.Int64("min_refresh_time_sec", 604800,
		"minimum time window between two refreshes for a given user.")
	x = flag.Int64("refresh_user_rollout_percent", 100,
		"temporary flag to ramp up the refresh user rpc")
	aVeryLongVariableName = stats.GetVarInt("refresh-user-count")
)

func _() {
	var privateKey2 = &Block{Type: "RSA PRIVATE KEY",
					Headers: map[string]string{},
					Bytes: []uint8{0x30, 0x82, 0x1, 0x3a, 0x2, 0x1, 0x0, 0x2,
			0x41, 0x0, 0xb2, 0x99, 0xf, 0x49, 0xc4, 0x7d, 0xfa, 0x8c,
			0xd4, 0x0, 0xae, 0x6a, 0x4d, 0x1b, 0x8a, 0x3b, 0x6a, 0x13,
			0x64, 0x2b, 0x23, 0xf2, 0x8b, 0x0, 0x3b, 0xfb, 0x97, 0x79,
		},
	}
}


func _() {
	var Universe = Scope {
		Names: map[string]*Ident {
			// basic types
			"bool": nil,
			"byte": nil,
			"int8": nil,
			"int16": nil,
			"int32": nil,
			"int64": nil,
			"uint8": nil,
			"uint16": nil,
			"uint32": nil,
			"uint64": nil,
			"float32": nil,
			"float64": nil,
			"string": nil,

			// convenience types
			"int": nil,
			"uint": nil,
			"uintptr": nil,
			"float": nil,

			// constants
			"false": nil,
			"true": nil,
			"iota": nil,
			"nil": nil,

			// functions
			"cap": nil,
			"len": nil,
			"new": nil,
			"make": nil,
			"panic": nil,
			"panicln": nil,
			"print": nil,
			"println": nil,
		},
	}
}


// alignment of map composite entries
var _ = map[int]int{
	// small key sizes: always align even if size ratios are large
	a: a,
	abcdefghabcdefgh: a,
	ab: a,
	abc: a,
	abcdefgabcdefg: a,
	abcd: a,
	abcde: a,
	abcdef: a,

	// mixed key sizes: align when key sizes change within accepted ratio
	abcdefgh: a,
	abcdefghabcdefg: a,
	abcdefghij: a,
	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij: a, // outlier - do not align with previous line
	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij: a, // align with previous line

	ab: a, // do not align with previous line
	abcde: a, // align with previous line
}

// alignment of map composite entries: test cases from issue 3965
// aligned
var _ = T1{
	a:                    x,
	b:                    y,
	cccccccccccccccccccc: z,
}

// not aligned
var _ = T2{
	a: x,
	b: y,
	ccccccccccccccccccccc: z,
}

// aligned
var _ = T3{
	aaaaaaaaaaaaaaaaaaaa: x,
	b:                    y,
	c:                    z,
}

// not aligned
var _ = T4{
	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x,
	b:                                       y,
	c:                                       z,
}


// no alignment of map composite entries if they are not the first entry on a line
var _ = T{0: 0} // not aligned
var _ = T{0: 0, // not aligned
	1: 1, // aligned
	22: 22, // aligned
	333: 333, 1234: 12, 12345: 0, // first on line aligned
}


// test cases form issue 8685
// not aligned
var _ = map[int]string{1: "spring", 2: "summer",
					3:             "autumn", 4: "winter"}

// not aligned
var _ = map[string]string{"a": "spring", "b": "summer",
	"c": "autumn", "d": "winter"}

// aligned
var _ = map[string]string{"a": "spring",
"b": "summer",
	"c": "autumn",
"d": "winter"}


func _() {
	var _ = T{
		a,	// must introduce trailing comma
	}
}


// formatting of function results
func _() func() {}
func _() func(int) { return nil }
func _() func(int) int { return nil }
func _() func(int) func(int) func() { return nil }


// formatting of consecutive single-line functions
func _() {}
func _() {}
func _() {}

func _() {}  // an empty line before this function
func _() {}
func _() {}

func _() { f(1, 2, 3) }
func _(x int) int { y := x; return y+1 }
func _() int { type T struct{}; var x T; return x }

// these must remain multi-line since they are multi-line in the source
func _() {
	f(1, 2, 3)
}
func _(x int) int {
	y := x; return y+1
}
func _() int {
	type T struct{}; var x T; return x
}


// making function declarations safe for new semicolon rules
func _() { /* single-line function because of "short-ish" comment */ }
func _() { /* multi-line function because of "long-ish" comment - much more comment text is following here */ /* and more */ }

func _() {
/* multi-line func because block is on multiple lines */ }


// ellipsis parameters
func _(...int)
func _(...*int)
func _(...[]int)
func _(...struct{})
func _(bool, ...interface{})
func _(bool, ...func())
func _(bool, ...func(...int))
func _(bool, ...map[string]int)
func _(bool, ...chan int)

func _(b bool, x ...int)
func _(b bool, x ...*int)
func _(b bool, x ...[]int)
func _(b bool, x ...struct{})
func _(x ...interface{})
func _(x ...func())
func _(x ...func(...int))
func _(x ...map[string]int)
func _(x ...chan int)


// these parameter lists must remain multi-line since they are multi-line in the source
func _(bool,
int) {
}
func _(x bool,
y int) {
}
func _(x,
y bool) {
}
func _(bool, // comment
int) {
}
func _(x bool, // comment
y int) {
}
func _(x, // comment
y bool) {
}
func _(bool, // comment
// comment
int) {
}
func _(x bool, // comment
// comment
y int) {
}
func _(x, // comment
// comment
y bool) {
}
func _(bool,
// comment
int) {
}
func _(x bool,
// comment
y int) {
}
func _(x,
// comment
y bool) {
}
func _(x, // comment
y,// comment
z bool) {
}
func _(x, // comment
	y,// comment
	z bool) {
}
func _(x int,	// comment
	y float,	// comment
	z bool) {
}


// properly indent multi-line signatures
func ManageStatus(in <-chan *Status, req <-chan Request,
stat chan<- *TargetInfo,
TargetHistorySize int) {
}

func MultiLineSignature0(
a, b, c int,
) {}

func MultiLineSignature1(
a, b, c int,
u, v, w float,
) {}

func MultiLineSignature2(
a, b,
c int,
) {}

func MultiLineSignature3(
a, b,
c int, u, v,
w float,
		x ...int) {}

func MultiLineSignature4(
a, b, c int,
u, v,
w float,
		x ...int) {}

func MultiLineSignature5(
a, b, c int,
u, v, w float,
p, q,
r string,
		x ...int) {}

// make sure it also works for methods in interfaces
type _ interface {
MultiLineSignature0(
a, b, c int,
)

MultiLineSignature1(
a, b, c int,
u, v, w float,
)

MultiLineSignature2(
a, b,
c int,
)

MultiLineSignature3(
a, b,
c int, u, v,
w float,
		x ...int)

MultiLineSignature4(
a, b, c int,
u, v,
w float,
		x ...int)

MultiLineSignature5(
a, b, c int,
u, v, w float,
p, q,
r string,
		x ...int)
}

// omit superfluous parentheses in parameter lists
func _((int))
func _((((((int))))))
func _(x (int))
func _(x (((((int))))))
func _(x, y (int))
func _(x, y (((((int))))))

func _() (int)
func _() ((int))
func _() ((((((int))))))

func _() (x int)
func _() (x (int))
func _() (x (((((int))))))

// special cases: some channel types require parentheses
func _(x chan(<-chan int))
func _(x (chan(<-chan int)))
func _(x ((((chan(<-chan int))))))

func _(x chan<-(chan int))
func _(x (chan<-(chan int)))
func _(x ((((chan<-(chan int))))))

// don't introduce comma after last parameter if the closing ) is on the same line
// even if the parameter type itself is multi-line (test cases from issue 4533)
func _(...interface{})
func _(...interface {
	m()
	n()
}) // no extra comma between } and )

func (t *T) _(...interface{})
func (t *T) _(...interface {
	m()
	n()
}) // no extra comma between } and )

func _(interface{})
func _(interface {
	m()
}) // no extra comma between } and )

func _(struct{})
func _(struct {
	x int
	y int
}) // no extra comma between } and )
