// 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 com.google.gerrit.truth.ConfigSubject.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.extensions.client.Theme;
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 {
  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 Theme t;
    public Theme td;
    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
      i.t = Theme.DEFAULT;
      i.td = Theme.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";
    in.t = Theme.MIDNIGHT;

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

    assertThat(cfg).stringValue(SECT, SUB, "CONSTANT").isNull();
    assertThat(cfg).stringValue(SECT, SUB, "missing").isNull();
    assertThat(cfg).booleanValue(SECT, SUB, "b", false).isEqualTo(in.b);
    assertThat(cfg).booleanValue(SECT, SUB, "bb", false).isEqualTo(in.bb);
    assertThat(cfg).intValue(SECT, SUB, "i", 0).isEqualTo(0);
    assertThat(cfg).intValue(SECT, SUB, "ii", 0).isEqualTo(in.ii);
    assertThat(cfg).longValue(SECT, SUB, "l", 0L).isEqualTo(0L);
    assertThat(cfg).longValue(SECT, SUB, "ll", 0L).isEqualTo(in.ll);
    assertThat(cfg).stringValue(SECT, SUB, "s").isEqualTo(in.s);
    assertThat(cfg).stringValue(SECT, SUB, "sd").isNull();
    assertThat(cfg).stringValue(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();
    assertThat(out.t).isEqualTo(in.t);
    assertThat(out.td).isEqualTo(d.td);
  }

  @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);
  }
}
