// Copyright (C) 2010 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 static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

import com.google.gerrit.testing.GerritBaseTests;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;

public class ConfigUtilTest extends GerritBaseTests {
  private static final String SECT = "foo";
  private static final String SUB = "bar";

  static class SectionInfo {
    public static final String CONSTANT = "42";
    public transient String missing;
    public int i;
    public Integer ii;
    public Integer id;
    public long l;
    public Long ll;
    public Long ld;
    public boolean b;
    public Boolean bb;
    public Boolean bd;
    public String s;
    public String sd;
    public String nd;
    public List<String> list;
    public Map<String, String> map;

    static SectionInfo defaults() {
      SectionInfo i = new SectionInfo();
      i.i = 1;
      i.ii = 2;
      i.id = 3;
      i.l = 4L;
      i.ll = 5L;
      i.ld = 6L;
      i.b = true;
      i.bb = false;
      i.bd = true;
      i.s = "foo";
      i.sd = "bar";
      // i.nd = null; // Don't need to explicitly set it; it's null by default
      return i;
    }
  }

  @Test
  public void storeLoadSection() throws Exception {
    SectionInfo d = SectionInfo.defaults();
    SectionInfo in = new SectionInfo();
    in.missing = "42";
    in.i = 1;
    in.ii = 43;
    in.l = 4L;
    in.ll = -43L;
    in.b = false;
    in.bb = true;
    in.bd = false;
    in.s = "baz";

    Config cfg = new Config();
    ConfigUtil.storeSection(cfg, SECT, SUB, in, d);

    assertThat(cfg.getString(SECT, SUB, "CONSTANT")).isNull();
    assertThat(cfg.getString(SECT, SUB, "missing")).isNull();
    assertThat(cfg.getBoolean(SECT, SUB, "b", false)).isEqualTo(in.b);
    assertThat(cfg.getBoolean(SECT, SUB, "bb", false)).isEqualTo(in.bb);
    assertThat(cfg.getInt(SECT, SUB, "i", 0)).isEqualTo(0);
    assertThat(cfg.getInt(SECT, SUB, "ii", 0)).isEqualTo(in.ii);
    assertThat(cfg.getLong(SECT, SUB, "l", 0L)).isEqualTo(0L);
    assertThat(cfg.getLong(SECT, SUB, "ll", 0L)).isEqualTo(in.ll);
    assertThat(cfg.getString(SECT, SUB, "s")).isEqualTo(in.s);
    assertThat(cfg.getString(SECT, SUB, "sd")).isNull();
    assertThat(cfg.getString(SECT, SUB, "nd")).isNull();

    SectionInfo out = new SectionInfo();
    ConfigUtil.loadSection(cfg, SECT, SUB, out, d, null);
    assertThat(out.i).isEqualTo(in.i);
    assertThat(out.ii).isEqualTo(in.ii);
    assertThat(out.id).isEqualTo(d.id);
    assertThat(out.l).isEqualTo(in.l);
    assertThat(out.ll).isEqualTo(in.ll);
    assertThat(out.ld).isEqualTo(d.ld);
    assertThat(out.b).isEqualTo(in.b);
    assertThat(out.bb).isEqualTo(in.bb);
    assertThat(out.bd).isNull();
    assertThat(out.s).isEqualTo(in.s);
    assertThat(out.sd).isEqualTo(d.sd);
    assertThat(out.nd).isNull();
  }

  @Test
  public void mergeSection() throws Exception {
    SectionInfo d = SectionInfo.defaults();
    Config cfg = new Config();
    ConfigUtil.storeSection(cfg, SECT, SUB, d, d);

    SectionInfo in = new SectionInfo();
    in.i = 42;

    SectionInfo out = new SectionInfo();
    ConfigUtil.loadSection(cfg, SECT, SUB, out, d, in);
    // Check original values preserved
    assertThat(out.id).isEqualTo(d.id);
    // Check merged values
    assertThat(out.i).isEqualTo(in.i);
    // Check that boolean attribute not nullified
    assertThat(out.bb).isFalse();
  }

  @Test
  public void timeUnit() {
    assertThat(parse("0")).isEqualTo(ms(0, MILLISECONDS));
    assertThat(parse("2ms")).isEqualTo(ms(2, MILLISECONDS));
    assertThat(parse("200 milliseconds")).isEqualTo(ms(200, MILLISECONDS));

    assertThat(parse("0s")).isEqualTo(ms(0, SECONDS));
    assertThat(parse("2s")).isEqualTo(ms(2, SECONDS));
    assertThat(parse("231sec")).isEqualTo(ms(231, SECONDS));
    assertThat(parse("1second")).isEqualTo(ms(1, SECONDS));
    assertThat(parse("300 seconds")).isEqualTo(ms(300, SECONDS));

    assertThat(parse("2m")).isEqualTo(ms(2, MINUTES));
    assertThat(parse("2min")).isEqualTo(ms(2, MINUTES));
    assertThat(parse("1 minute")).isEqualTo(ms(1, MINUTES));
    assertThat(parse("10 minutes")).isEqualTo(ms(10, MINUTES));

    assertThat(parse("5h")).isEqualTo(ms(5, HOURS));
    assertThat(parse("5hr")).isEqualTo(ms(5, HOURS));
    assertThat(parse("1hour")).isEqualTo(ms(1, HOURS));
    assertThat(parse("48hours")).isEqualTo(ms(48, HOURS));

    assertThat(parse("5 h")).isEqualTo(ms(5, HOURS));
    assertThat(parse("5 hr")).isEqualTo(ms(5, HOURS));
    assertThat(parse("1 hour")).isEqualTo(ms(1, HOURS));
    assertThat(parse("48 hours")).isEqualTo(ms(48, HOURS));
    assertThat(parse("48 \t \r hours")).isEqualTo(ms(48, HOURS));

    assertThat(parse("4d")).isEqualTo(ms(4, DAYS));
    assertThat(parse("1day")).isEqualTo(ms(1, DAYS));
    assertThat(parse("14days")).isEqualTo(ms(14, DAYS));

    assertThat(parse("1w")).isEqualTo(ms(7, DAYS));
    assertThat(parse("1week")).isEqualTo(ms(7, DAYS));
    assertThat(parse("2w")).isEqualTo(ms(14, DAYS));
    assertThat(parse("2weeks")).isEqualTo(ms(14, DAYS));

    assertThat(parse("1mon")).isEqualTo(ms(30, DAYS));
    assertThat(parse("1month")).isEqualTo(ms(30, DAYS));
    assertThat(parse("2mon")).isEqualTo(ms(60, DAYS));
    assertThat(parse("2months")).isEqualTo(ms(60, DAYS));

    assertThat(parse("1y")).isEqualTo(ms(365, DAYS));
    assertThat(parse("1year")).isEqualTo(ms(365, DAYS));
    assertThat(parse("2years")).isEqualTo(ms(365 * 2, DAYS));
  }

  private static long ms(int cnt, TimeUnit unit) {
    return MILLISECONDS.convert(cnt, unit);
  }

  private static long parse(String string) {
    return ConfigUtil.getTimeUnit(string, 1, MILLISECONDS);
  }
}
