// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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.gitiles;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

import com.google.common.cache.CacheBuilder;
import java.util.Optional;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.eclipse.jgit.lib.Config;
import org.joda.time.Duration;

/** Utilities for working with {@link Config} objects. */
public class ConfigUtil {
  /**
   * Read a duration value from the configuration.
   *
   * <p>Durations can be written with unit suffixes, for example {@code "1 s"} or {@code "5 days"}.
   * If units are not specified, milliseconds are assumed.
   *
   * @param config JGit config object.
   * @param section section to read, e.g. "google"
   * @param subsection subsection to read, e.g. "bigtable"
   * @param name variable to read, e.g. "deadline".
   * @param defaultValue value to use when the value is not assigned.
   * @return a standard duration representing the time read, or defaultValue.
   */
  public static Duration getDuration(
      Config config,
      String section,
      String subsection,
      String name,
      @Nullable Duration defaultValue) {
    long m = config.getTimeUnit(section, subsection, name, -1, MILLISECONDS);
    return m == -1 ? defaultValue : Duration.millis(m);
  }

  /**
   * Get a {@link CacheBuilder} from a config.
   *
   * @param config JGit config object.
   * @param name name of the cache subsection under the "cache" section.
   * @return a new cache builder.
   */
  public static CacheBuilder<Object, Object> getCacheBuilder(Config config, String name) {
    CacheBuilder<Object, Object> b = CacheBuilder.newBuilder();
    try {
      if (config.getString("cache", name, "maximumWeight") != null) {
        b.maximumWeight(config.getLong("cache", name, "maximumWeight", 20 << 20));
      }
      if (config.getString("cache", name, "maximumSize") != null) {
        b.maximumSize(config.getLong("cache", name, "maximumSize", 16384));
      }
      Duration expireAfterWrite = getDuration(config, "cache", name, "expireAfterWrite", null);
      if (expireAfterWrite != null) {
        b.expireAfterWrite(expireAfterWrite.getMillis(), TimeUnit.MILLISECONDS);
      }
      Duration expireAfterAccess = getDuration(config, "cache", name, "expireAfterAccess", null);
      if (expireAfterAccess != null) {
        b.expireAfterAccess(expireAfterAccess.getMillis(), TimeUnit.MILLISECONDS);
      }
      // Add other methods as needed.
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException("Error getting CacheBuilder for " + name, e);
    } catch (IllegalStateException e) {
      throw new IllegalStateException("Error getting CacheBuilder for " + name, e);
    }
    return b;
  }

  /**
   * Get a {@link TimeZone} from a config.
   *
   * @param config JGit config object.
   * @param section section to read, e.g. "gitiles".
   * @param subsection subsection to read, e.g. "subsection".
   * @param name variable to read, e.g. "fixedTimeZone".
   * @return a time zone read from parsing the specified config string value, or {@link
   *     Optional#empty()} if not present. As in the behavior of {@link
   *     TimeZone#getTimeZone(String)}, unknown time zones are treated as GMT.
   */
  public static Optional<TimeZone> getTimeZone(
      Config config, String section, String subsection, String name) {
    return Optional.ofNullable(config.getString(section, subsection, name))
        .map(TimeZone::getTimeZone);
  }

  private ConfigUtil() {}
}
