blob: 4c8ec98a4c2103abc192bf1347a377e467947e94 [file] [log] [blame]
// Copyright 2019 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"time"
"google.golang.org/genproto/googleapis/type/dayofweek"
"go.chromium.org/luci/common/errors"
"go.chromium.org/luci/config/validation"
)
// isSameDay returns whether the given time.Weekday and dayofweek.DayOfWeek
// represent the same day of the week.
func isSameDay(wkd time.Weekday, dow dayofweek.DayOfWeek) bool {
switch dow {
case dayofweek.DayOfWeek_DAY_OF_WEEK_UNSPECIFIED:
return false
case dayofweek.DayOfWeek_SUNDAY:
// time.Weekday has Sunday == 0, dayofweek.DayOfWeek has Sunday == 7.
return wkd == time.Sunday
default:
// For all other values, time.Weekday == dayofweek.DayOfWeek.
return int(wkd) == int(dow)
}
}
// mostRecentStart returns the most recent start time for this schedule relative
// to the given time. The date in the returned time.Time will be the most recent
// date falling on the day of the week specified in this schedule which results
// in the returned time being equal to or before the given time.
func (s *Schedule) mostRecentStart(now time.Time) (time.Time, error) {
t, err := s.GetStart().toTime()
if err != nil {
return time.Time{}, err
}
now = now.In(t.Location())
// toTime returns a time relative to the current date. Change it to be relative to the given date.
t = time.Date(now.Year(), now.Month(), now.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
if s.GetStart().Day == dayofweek.DayOfWeek_DAY_OF_WEEK_UNSPECIFIED {
return time.Time{}, errors.Reason("day must be specified").Err()
}
for !isSameDay(t.Weekday(), s.GetStart().Day) {
t = t.Add(time.Hour * -24)
}
if t.After(now) {
t = t.Add(time.Hour * -24 * 7)
}
return t, nil
}
// Validate validates this schedule.
func (s *Schedule) Validate(c *validation.Context) {
if s.GetMin() < 0 {
c.Errorf("minimum amount must be non-negative")
}
if s.GetMax() < 0 {
c.Errorf("maximum amount must be non-negative")
}
if s.GetMin() > s.GetMax() {
c.Errorf("minimum amount must not exceed maximum amount")
}
c.Enter("length")
s.GetLength().Validate(c)
switch n, err := s.Length.ToSeconds(); {
case err != nil:
c.Errorf("%s", err)
case n == 0:
c.Errorf("duration or seconds is required")
}
c.Exit()
c.Enter("start")
s.GetStart().Validate(c)
c.Exit()
}