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

package main

import (
	"go/ast"
	"go/token"
	"strings"
)

func init() {
	register(timefileinfoFix)
}

var timefileinfoFix = fix{
	"time+fileinfo",
	"2011-11-29",
	timefileinfo,
	`Rewrite for new time and os.FileInfo APIs.

This fix applies some of the more mechanical changes,
but most code will still need manual cleanup.

http://codereview.appspot.com/5392041
http://codereview.appspot.com/5416060
`,
}

var timefileinfoTypeConfig = &TypeConfig{
	Type: map[string]*Type{
		"os.File": &Type{
			Method: map[string]string{
				"Readdir": "func() []*os.FileInfo",
				"Stat":    "func() (*os.FileInfo, error)",
			},
		},
		"time.Time": &Type{
			Method: map[string]string{
				"Seconds":     "time.raw",
				"Nanoseconds": "time.raw",
			},
		},
	},
	Func: map[string]string{
		"ioutil.ReadDir":              "([]*os.FileInfo, error)",
		"os.Stat":                     "(*os.FileInfo, error)",
		"os.Lstat":                    "(*os.FileInfo, error)",
		"time.LocalTime":              "*time.Time",
		"time.UTC":                    "*time.Time",
		"time.SecondsToLocalTime":     "*time.Time",
		"time.SecondsToUTC":           "*time.Time",
		"time.NanosecondsToLocalTime": "*time.Time",
		"time.NanosecondsToUTC":       "*time.Time",
		"time.Parse":                  "(*time.Time, error)",
		"time.Nanoseconds":            "time.raw",
		"time.Seconds":                "time.raw",
	},
}

// timefileinfoIsOld reports whether f has evidence of being
// "old code", from before the API changes.  Evidence means:
//
//	a mention of *os.FileInfo (the pointer)
//	a mention of *time.Time (the pointer)
//	a mention of old functions from package time
//	an attempt to call time.UTC
//
func timefileinfoIsOld(f *ast.File, typeof map[interface{}]string) bool {
	old := false
	
	// called records the expressions that appear as
	// the function part of a function call, so that
	// we can distinguish a ref to the possibly new time.UTC
	// from the definitely old time.UTC() function call.
	called := make(map[interface{}]bool)

	before := func(n interface{}) {
		if old {
			return
		}
		if star, ok := n.(*ast.StarExpr); ok {
			if isPkgDot(star.X, "os", "FileInfo") || isPkgDot(star.X, "time", "Time") {
				old = true
				return
			}
		}
		if sel, ok := n.(*ast.SelectorExpr); ok {
			if isTopName(sel.X, "time") {
				if timefileinfoOldTimeFunc[sel.Sel.Name] {
					old = true
					return
				}
			}
			if typeof[sel.X] == "os.FileInfo" || typeof[sel.X] == "*os.FileInfo" {
				switch sel.Sel.Name {
				case "Mtime_ns", "IsDirectory", "IsRegular":
					old = true
					return
				case "Name", "Mode", "Size":
					if !called[sel] {
						old = true
						return
					}
				}
			}
		}
		call, ok := n.(*ast.CallExpr)
		if ok && isPkgDot(call.Fun, "time", "UTC") {
			old = true
			return
		}
		if ok {
			called[call.Fun] = true
		}
	}
	walkBeforeAfter(f, before, nop)
	return old
}

var timefileinfoOldTimeFunc = map[string]bool{
	"LocalTime":              true,
	"SecondsToLocalTime":     true,
	"SecondsToUTC":           true,
	"NanosecondsToLocalTime": true,
	"NanosecondsToUTC":       true,
	"Seconds":                true,
	"Nanoseconds":            true,
}

var isTimeNow = map[string]bool{
	"LocalTime":   true,
	"UTC":         true,
	"Seconds":     true,
	"Nanoseconds": true,
}

func timefileinfo(f *ast.File) bool {
	if !imports(f, "os") && !imports(f, "time") && !imports(f, "io/ioutil") {
		return false
	}

	typeof, _ := typecheck(timefileinfoTypeConfig, f)

	if !timefileinfoIsOld(f, typeof) {
		return false
	}

	fixed := false
	walk(f, func(n interface{}) {
		p, ok := n.(*ast.Expr)
		if !ok {
			return
		}
		nn := *p

		// Rewrite *os.FileInfo and *time.Time to drop the pointer.
		if star, ok := nn.(*ast.StarExpr); ok {
			if isPkgDot(star.X, "os", "FileInfo") || isPkgDot(star.X, "time", "Time") {
				fixed = true
				*p = star.X
				return
			}
		}

		// Rewrite old time API calls to new calls.
		// The code will still not compile after this edit,
		// but the compiler will catch that, and the replacement
		// code will be the correct functions to use in the new API.
		if sel, ok := nn.(*ast.SelectorExpr); ok && isTopName(sel.X, "time") {
			fn := sel.Sel.Name
			if fn == "LocalTime" || fn == "Seconds" || fn == "Nanoseconds" {
				fixed = true
				sel.Sel.Name = "Now"
				return
			}
		}

		if call, ok := nn.(*ast.CallExpr); ok {
			if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
				// Rewrite time.UTC but only when called (there's a new time.UTC var now).
				if isPkgDot(sel, "time", "UTC") {
					fixed = true
					sel.Sel.Name = "Now"
					// rewrite time.Now() into time.Now().UTC()
					*p = &ast.CallExpr{
						Fun: &ast.SelectorExpr{
							X:   call,
							Sel: ast.NewIdent("UTC"),
						},
					}
					return
				}

				// Rewrite conversions.
				if ok && isTopName(sel.X, "time") && len(call.Args) == 1 {
					fn := sel.Sel.Name
					switch fn {
					case "SecondsToLocalTime", "SecondsToUTC",
						"NanosecondsToLocalTime", "NanosecondsToUTC":
						fixed = true
						sel.Sel.Name = "Unix"
						call.Args = append(call.Args, nil)
						if strings.HasPrefix(fn, "Seconds") {
							// Unix(sec, 0)
							call.Args[1] = ast.NewIdent("0")
						} else {
							// Unix(0, nsec)
							call.Args[1] = call.Args[0]
							call.Args[0] = ast.NewIdent("0")
						}
						if strings.HasSuffix(fn, "ToUTC") {
							// rewrite call into call.UTC()
							*p = &ast.CallExpr{
								Fun: &ast.SelectorExpr{
									X:   call,
									Sel: ast.NewIdent("UTC"),
								},
							}
						}
						return
					}
				}

				// Rewrite method calls.
				switch typeof[sel.X] {
				case "*time.Time", "time.Time":
					switch sel.Sel.Name {
					case "Seconds":
						fixed = true
						sel.Sel.Name = "Unix"
						return
					case "Nanoseconds":
						fixed = true
						sel.Sel.Name = "UnixNano"
						return
					}

				case "*os.FileInfo", "os.FileInfo":
					switch sel.Sel.Name {
					case "IsDirectory":
						fixed = true
						sel.Sel.Name = "IsDir"
						return
					case "IsRegular":
						fixed = true
						sel.Sel.Name = "IsDir"
						*p = &ast.UnaryExpr{
							Op: token.NOT,
							X:  call,
						}
						return
					}
				}
			}
		}

		// Rewrite subtraction of two times.
		// Cannot handle +=/-=.
		if bin, ok := nn.(*ast.BinaryExpr); ok &&
			bin.Op == token.SUB &&
			(typeof[bin.X] == "time.raw" || typeof[bin.Y] == "time.raw") {
			fixed = true
			*p = &ast.CallExpr{
				Fun: &ast.SelectorExpr{
					X:   bin.X,
					Sel: ast.NewIdent("Sub"),
				},
				Args: []ast.Expr{bin.Y},
			}
		}

		// Rewrite field references for os.FileInfo.
		if sel, ok := nn.(*ast.SelectorExpr); ok {
			if typ := typeof[sel.X]; typ == "*os.FileInfo" || typ == "os.FileInfo" {
				addCall := false
				switch sel.Sel.Name {
				case "Name", "Size", "Mode":
					fixed = true
					addCall = true
				case "Mtime_ns":
					fixed = true
					sel.Sel.Name = "ModTime"
					addCall = true
				}
				if addCall {
					*p = &ast.CallExpr{
						Fun: sel,
					}
					return
				}
			}
		}
	})

	return true
}
