// Copyright (C) 2014 The Android Open Source Project
//
// 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 com.google.gerrit.server.config;

import com.google.common.annotations.VisibleForTesting;

import org.eclipse.jgit.lib.Config;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
import org.joda.time.MutableDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

public class ScheduleConfig {
  private static final Logger log = LoggerFactory
      .getLogger(ScheduleConfig.class);
  public static final long MISSING_CONFIG = -1L;
  public static final long INVALID_CONFIG = -2L;
  private static final String KEY_INTERVAL = "interval";
  private static final String KEY_STARTTIME = "startTime";

  private final Config rc;
  private final String section;
  private final String subsection;
  private final String keyInterval;
  private final String keyStartTime;
  private final long initialDelay;
  private final long interval;

  public ScheduleConfig(Config rc, String section) {
    this(rc, section, null);
  }

  public ScheduleConfig(Config rc, String section, String subsection) {
    this(rc, section, subsection, DateTime.now());
  }

  public ScheduleConfig(Config rc, String section, String subsection,
      String keyInterval, String keyStartTime) {
    this(rc, section, subsection, keyInterval, keyStartTime, DateTime.now());
  }

  @VisibleForTesting
  ScheduleConfig(Config rc, String section, String subsection, DateTime now) {
    this(rc, section, subsection, KEY_INTERVAL, KEY_STARTTIME, now);
  }

  @VisibleForTesting
  ScheduleConfig(Config rc, String section, String subsection,
      String keyInterval, String keyStartTime, DateTime now) {
    this.rc = rc;
    this.section = section;
    this.subsection = subsection;
    this.keyInterval = keyInterval;
    this.keyStartTime = keyStartTime;
    this.interval = interval(rc, section, subsection, keyInterval);
    if (interval > 0) {
      this.initialDelay = initialDelay(rc, section, subsection, keyStartTime, now,
          interval);
    } else {
      this.initialDelay = interval;
    }
  }

  /**
   * Milliseconds between constructor invocation and first event time.
   * <p>
   * If there is any lag between the constructor invocation and queuing the
   * object into an executor the event will run later, as there is no method
   * to adjust for the scheduling delay.
   */
  public long getInitialDelay() {
    return initialDelay;
  }

  /** Number of milliseconds between events. */
  public long getInterval() {
    return interval;
  }

  private static long interval(Config rc, String section, String subsection,
      String keyInterval) {
    long interval = MISSING_CONFIG;
    try {
      interval =
          ConfigUtil.getTimeUnit(rc, section, subsection, keyInterval, -1,
              TimeUnit.MILLISECONDS);
      if (interval == MISSING_CONFIG) {
        log.info(MessageFormat.format(
            "{0} schedule parameter \"{0}.{1}\" is not configured", section,
            keyInterval));
      }
    } catch (IllegalArgumentException e) {
      log.error(MessageFormat.format(
          "Invalid {0} schedule parameter \"{0}.{1}\"", section, keyInterval),
          e);
      interval = INVALID_CONFIG;
    }
    return interval;
  }

  private static long initialDelay(Config rc, String section,
      String subsection, String keyStartTime, DateTime now, long interval) {
    long delay = MISSING_CONFIG;
    String start = rc.getString(section, subsection, keyStartTime);
    try {
      if (start != null) {
        DateTimeFormatter formatter;
        MutableDateTime startTime = now.toMutableDateTime();
        try {
          formatter = ISODateTimeFormat.hourMinute();
          LocalTime firstStartTime = formatter.parseLocalTime(start);
          startTime.hourOfDay().set(firstStartTime.getHourOfDay());
          startTime.minuteOfHour().set(firstStartTime.getMinuteOfHour());
        } catch (IllegalArgumentException e1) {
          formatter = DateTimeFormat.forPattern("E HH:mm")
              .withLocale(Locale.US);
          LocalDateTime firstStartDateTime = formatter.parseLocalDateTime(start);
          startTime.dayOfWeek().set(firstStartDateTime.getDayOfWeek());
          startTime.hourOfDay().set(firstStartDateTime.getHourOfDay());
          startTime.minuteOfHour().set(firstStartDateTime.getMinuteOfHour());
        }
        startTime.secondOfMinute().set(0);
        startTime.millisOfSecond().set(0);
        long s = startTime.getMillis();
        long n = now.getMillis();
        delay = (s - n) % interval;
        if (delay <= 0) {
          delay += interval;
        }
      } else {
        log.info(MessageFormat.format(
            "{0} schedule parameter \"{0}.{1}\" is not configured", section,
            keyStartTime));
      }
    } catch (IllegalArgumentException e2) {
      log.error(
          MessageFormat.format("Invalid {0} schedule parameter \"{0}.{1}\"",
              section, keyStartTime), e2);
      delay = INVALID_CONFIG;
    }
    return delay;
  }

  @Override
  public String toString() {
    StringBuilder b = new StringBuilder();
    b.append(formatValue(keyInterval));
    b.append(", ");
    b.append(formatValue(keyStartTime));
    return b.toString();
  }

  private String formatValue(String key) {
    StringBuilder b = new StringBuilder();
    b.append(section);
    if (subsection != null) {
      b.append(".");
      b.append(subsection);
    }
    b.append(".");
    b.append(key);
    String value = rc.getString(section, subsection, key);
    if (value != null) {
      b.append(" = ");
      b.append(value);
    } else {
      b.append(": NA");
    }
    return b.toString();
  }
}
