// Copyright (C) 2009 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.pgm.init;

import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.Section;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.securestore.SecureStore;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.List;


public class UpgradeFrom2_0_xTest extends InitTestCase {

  @Test
  public void testUpgrade() throws IOException, ConfigInvalidException {
    final File p = newSitePath();
    final SitePaths site = new SitePaths(p);
    assertTrue(site.isNew);
    assertTrue(site.site_path.mkdir());
    assertTrue(site.etc_dir.mkdir());

    for (String n : UpgradeFrom2_0_x.etcFiles) {
      Writer w = new FileWriter(new File(p, n));
      try {
        w.write("# " + n + "\n");
      } finally {
        w.close();
      }
    }

    FileBasedConfig old =
        new FileBasedConfig(new File(p, "gerrit.config"), FS.DETECTED);

    old.setString("ldap", null, "username", "ldap.user");
    old.setString("ldap", null, "password", "ldap.s3kr3t");

    old.setString("sendemail", null, "smtpUser", "email.user");
    old.setString("sendemail", null, "smtpPass", "email.s3kr3t");
    old.save();

    final InMemorySecureStore secureStore = new InMemorySecureStore();
    final InitFlags flags =
        new InitFlags(site, secureStore, Collections.<String> emptyList());
    final ConsoleUI ui = createStrictMock(ConsoleUI.class);
    Section.Factory sections = new Section.Factory() {
      @Override
      public Section get(String name, String subsection) {
        return new Section(flags, site, secureStore, ui, name, subsection);
      }
    };

    expect(ui.yesno(eq(true), eq("Upgrade '%s'"), eq(p.getCanonicalPath())))
        .andReturn(true);
    replay(ui);

    UpgradeFrom2_0_x u = new UpgradeFrom2_0_x(site, flags, ui, sections);
    assertTrue(u.isNeedUpgrade());
    u.run();
    assertFalse(u.isNeedUpgrade());
    verify(ui);

    for (String n : UpgradeFrom2_0_x.etcFiles) {
      if ("gerrit.config".equals(n)) continue;
      if ("secure.config".equals(n)) continue;
      assertEquals("# " + n + "\n",//
          new String(IO.readFully(new File(site.etc_dir, n)), "UTF-8"));
    }

    FileBasedConfig cfg = new FileBasedConfig(site.gerrit_config, FS.DETECTED);
    cfg.load();

    assertEquals("email.user", cfg.getString("sendemail", null, "smtpUser"));
    assertNull(cfg.getString("sendemail", null, "smtpPass"));
    assertEquals("email.s3kr3t", secureStore.get("sendemail", null, "smtpPass"));

    assertEquals("ldap.user", cfg.getString("ldap", null, "username"));
    assertNull(cfg.getString("ldap", null, "password"));
    assertEquals("ldap.s3kr3t", secureStore.get("ldap", null, "password"));

    u.run();
  }

  private static class InMemorySecureStore extends SecureStore {
    private final Config cfg = new Config();

    @Override
    public String[] getList(String section, String subsection, String name) {
      return cfg.getStringList(section, subsection, name);
    }

    @Override
    public void setList(String section, String subsection, String name,
        List<String> values) {
      cfg.setStringList(section, subsection, name, values);
    }

    @Override
    public void unset(String section, String subsection, String name) {
      cfg.unset(section, subsection, name);
    }

    @Override
    public Iterable<EntryKey> list() {
      throw new UnsupportedOperationException("not used by tests");
    }
  }
}
