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

import (
	"syscall"
	"sync"
	"os"
)

// BUG(brainman): The Windows implementation assumes that
// this year's rules for daylight savings time apply to all previous
// and future years as well.

// TODO(brainman): use GetDynamicTimeZoneInformation, whenever possible (Vista and up),
// to improve on situation described in the bug above.

type zone struct {
	name                  string
	offset                int
	year                  int64
	month, day, dayofweek int
	hour, minute, second  int
	abssec                int64
	prev                  *zone
}

// BUG(rsc): On Windows, time zone abbreviations are unavailable.
// This package constructs them using the capital letters from a longer
// time zone description.

// Populate zone struct with Windows supplied information. Returns true, if data is valid.
func (z *zone) populate(bias, biasdelta int32, d *syscall.Systemtime, name []uint16) (dateisgood bool) {
	// name is 'Pacific Standard Time' but we want 'PST'.
	// Extract just capital letters.  It's not perfect but the
	// information we need is not available from the kernel.
	// Because time zone abbreviations are not unique,
	// Windows refuses to expose them.
	//
	// http://social.msdn.microsoft.com/Forums/eu/vclanguage/thread/a87e1d25-fb71-4fe0-ae9c-a9578c9753eb
	// http://stackoverflow.com/questions/4195948/windows-time-zone-abbreviations-in-asp-net
	short := make([]uint16, len(name))
	w := 0
	for _, c := range name {
		if 'A' <= c && c <= 'Z' {
			short[w] = c
			w++
		}
	}
	z.name = syscall.UTF16ToString(short[:w])

	z.offset = int(bias)
	z.year = int64(d.Year)
	z.month = int(d.Month)
	z.day = int(d.Day)
	z.dayofweek = int(d.DayOfWeek)
	z.hour = int(d.Hour)
	z.minute = int(d.Minute)
	z.second = int(d.Second)
	dateisgood = d.Month != 0
	if dateisgood {
		z.offset += int(biasdelta)
	}
	z.offset = -z.offset * 60
	return
}

// Pre-calculate cutoff time in seconds since the Unix epoch, if data is supplied in "absolute" format.
func (z *zone) preCalculateAbsSec() {
	if z.year != 0 {
		t := &Time{
			Year:   z.year,
			Month:  int(z.month),
			Day:    int(z.day),
			Hour:   int(z.hour),
			Minute: int(z.minute),
			Second: int(z.second),
		}
		z.abssec = t.Seconds()
		// Time given is in "local" time. Adjust it for "utc".
		z.abssec -= int64(z.prev.offset)
	}
}

// Convert zone cutoff time to sec in number of seconds since the Unix epoch, given particular year.
func (z *zone) cutoffSeconds(year int64) int64 {
	// Windows specifies daylight savings information in "day in month" format:
	// z.month is month number (1-12)
	// z.dayofweek is appropriate weekday (Sunday=0 to Saturday=6)
	// z.day is week within the month (1 to 5, where 5 is last week of the month)
	// z.hour, z.minute and z.second are absolute time
	t := &Time{
		Year:   year,
		Month:  int(z.month),
		Day:    1,
		Hour:   int(z.hour),
		Minute: int(z.minute),
		Second: int(z.second),
	}
	t = SecondsToUTC(t.Seconds())
	i := int(z.dayofweek) - t.Weekday()
	if i < 0 {
		i += 7
	}
	t.Day += i
	if week := int(z.day) - 1; week < 4 {
		t.Day += week * 7
	} else {
		// "Last" instance of the day.
		t.Day += 4 * 7
		if t.Day > months(year)[t.Month] {
			t.Day -= 7
		}
	}
	// Result is in "local" time. Adjust it for "utc".
	return t.Seconds() - int64(z.prev.offset)
}

// Is t before the cutoff for switching to z?
func (z *zone) isBeforeCutoff(t *Time) bool {
	var coff int64
	if z.year == 0 {
		// "day in month" format used
		coff = z.cutoffSeconds(t.Year)
	} else {
		// "absolute" format used
		coff = z.abssec
	}
	return t.Seconds() < coff
}

type zoneinfo struct {
	disabled         bool // daylight saving time is not used locally
	offsetIfDisabled int
	januaryIsStd     bool // is january 1 standard time?
	std, dst         zone
}

// Pick zone (std or dst) t time belongs to.
func (zi *zoneinfo) pickZone(t *Time) *zone {
	z := &zi.std
	if tz.januaryIsStd {
		if !zi.dst.isBeforeCutoff(t) && zi.std.isBeforeCutoff(t) {
			// after switch to daylight time and before the switch back to standard
			z = &zi.dst
		}
	} else {
		if zi.std.isBeforeCutoff(t) || !zi.dst.isBeforeCutoff(t) {
			// before switch to standard time or after the switch back to daylight
			z = &zi.dst
		}
	}
	return z
}

var tz zoneinfo
var initError os.Error
var onceSetupZone sync.Once

func setupZone() {
	var i syscall.Timezoneinformation
	if _, e := syscall.GetTimeZoneInformation(&i); e != 0 {
		initError = os.NewSyscallError("GetTimeZoneInformation", e)
		return
	}
	setupZoneFromTZI(&i)
}

func setupZoneFromTZI(i *syscall.Timezoneinformation) {
	if !tz.std.populate(i.Bias, i.StandardBias, &i.StandardDate, i.StandardName[0:]) {
		tz.disabled = true
		tz.offsetIfDisabled = tz.std.offset
		return
	}
	tz.std.prev = &tz.dst
	tz.dst.populate(i.Bias, i.DaylightBias, &i.DaylightDate, i.DaylightName[0:])
	tz.dst.prev = &tz.std
	tz.std.preCalculateAbsSec()
	tz.dst.preCalculateAbsSec()
	// Is january 1 standard time this year?
	t := UTC()
	tz.januaryIsStd = tz.dst.cutoffSeconds(t.Year) < tz.std.cutoffSeconds(t.Year)
}

var usPacific = syscall.Timezoneinformation{
	Bias: 8 * 60,
	StandardName: [32]uint16{
		'P', 'a', 'c', 'i', 'f', 'i', 'c', ' ', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e',
	},
	StandardDate: syscall.Systemtime{Month: 11, Day: 1, Hour: 2},
	DaylightName: [32]uint16{
		'P', 'a', 'c', 'i', 'f', 'i', 'c', ' ', 'D', 'a', 'y', 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e',
	},
	DaylightDate: syscall.Systemtime{Month: 3, Day: 2, Hour: 2},
	DaylightBias: -60,
}

func setupTestingZone() {
	setupZoneFromTZI(&usPacific)
}

// Look up the correct time zone (daylight savings or not) for the given unix time, in the current location.
func lookupTimezone(sec int64) (zone string, offset int) {
	onceSetupZone.Do(setupZone)
	if initError != nil {
		return "", 0
	}
	if tz.disabled {
		return "", tz.offsetIfDisabled
	}
	t := SecondsToUTC(sec)
	z := &tz.std
	if tz.std.year == 0 {
		// "day in month" format used
		z = tz.pickZone(t)
	} else {
		// "absolute" format used
		if tz.std.year == t.Year {
			// we have rule for the year in question
			z = tz.pickZone(t)
		} else {
			// we do not have any information for that year,
			// will assume standard offset all year around
		}
	}
	return z.name, z.offset
}

// lookupByName returns the time offset for the
// time zone with the given abbreviation. It only considers
// time zones that apply to the current system.
func lookupByName(name string) (off int, found bool) {
	onceSetupZone.Do(setupZone)
	if initError != nil {
		return 0, false
	}
	if tz.disabled {
		return tz.offsetIfDisabled, false
	}
	switch name {
	case tz.std.name:
		return tz.std.offset, true
	case tz.dst.name:
		return tz.dst.offset, true
	}
	return 0, false
}
