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

// Parse Plan 9 timezone(2) files.

package time

import (
	"runtime"
	"syscall"
)

func isSpace(r rune) bool {
	return r == ' ' || r == '\t' || r == '\n'
}

// Copied from strings to avoid a dependency.
func fields(s string) []string {
	// First count the fields.
	n := 0
	inField := false
	for _, rune := range s {
		wasInField := inField
		inField = !isSpace(rune)
		if inField && !wasInField {
			n++
		}
	}

	// Now create them.
	a := make([]string, n)
	na := 0
	fieldStart := -1 // Set to -1 when looking for start of field.
	for i, rune := range s {
		if isSpace(rune) {
			if fieldStart >= 0 {
				a[na] = s[fieldStart:i]
				na++
				fieldStart = -1
			}
		} else if fieldStart == -1 {
			fieldStart = i
		}
	}
	if fieldStart >= 0 { // Last field might end at EOF.
		a[na] = s[fieldStart:]
	}
	return a
}

func loadZoneDataPlan9(s string) (l *Location, err error) {
	f := fields(s)
	if len(f) < 4 {
		if len(f) == 2 && f[0] == "GMT" {
			return UTC, nil
		}
		return nil, badData
	}

	var zones [2]zone

	// standard timezone offset
	o, err := atoi(f[1])
	if err != nil {
		return nil, badData
	}
	zones[0] = zone{name: f[0], offset: o, isDST: false}

	// alternate timezone offset
	o, err = atoi(f[3])
	if err != nil {
		return nil, badData
	}
	zones[1] = zone{name: f[2], offset: o, isDST: true}

	// transition time pairs
	var tx []zoneTrans
	f = f[4:]
	for i := 0; i < len(f); i++ {
		zi := 0
		if i%2 == 0 {
			zi = 1
		}
		t, err := atoi(f[i])
		if err != nil {
			return nil, badData
		}
		t -= zones[0].offset
		tx = append(tx, zoneTrans{when: int64(t), index: uint8(zi)})
	}

	// Committed to succeed.
	l = &Location{zone: zones[:], tx: tx}

	// Fill in the cache with information about right now,
	// since that will be the most common lookup.
	sec, _, _ := now()
	for i := range tx {
		if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
			l.cacheStart = tx[i].when
			l.cacheEnd = omega
			if i+1 < len(tx) {
				l.cacheEnd = tx[i+1].when
			}
			l.cacheZone = &l.zone[tx[i].index]
		}
	}

	return l, nil
}

func loadZoneFilePlan9(name string) (*Location, error) {
	b, err := readFile(name)
	if err != nil {
		return nil, err
	}
	return loadZoneDataPlan9(string(b))
}

func initTestingZone() {
	z, err := loadLocation("America/Los_Angeles")
	if err != nil {
		panic("cannot load America/Los_Angeles for testing: " + err.Error())
	}
	z.name = "Local"
	localLoc = *z
}

func initLocal() {
	t, ok := syscall.Getenv("timezone")
	if ok {
		if z, err := loadZoneDataPlan9(t); err == nil {
			localLoc = *z
			return
		}
	} else {
		if z, err := loadZoneFilePlan9("/adm/timezone/local"); err == nil {
			localLoc = *z
			localLoc.name = "Local"
			return
		}
	}

	// Fall back to UTC.
	localLoc.name = "UTC"
}

func loadLocation(name string) (*Location, error) {
	z, err := loadZoneFile(runtime.GOROOT()+"/lib/time/zoneinfo.zip", name)
	if err != nil {
		return nil, err
	}
	z.name = name
	return z, nil
}

func forceZipFileForTesting(zipOnly bool) {
	// We only use the zip file anyway.
}
