// Copyright (C) 2013 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.googlesource.gerrit.plugins.gitiles;

import com.google.gerrit.pgm.init.InitFlags;
import com.google.gerrit.pgm.init.InitStep;
import com.google.gerrit.pgm.init.Section;
import com.google.gerrit.pgm.util.ConsoleUI;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;

import org.eclipse.jgit.storage.file.FileBasedConfig;

import java.io.File;
import java.io.IOException;

class InitGitiles implements InitStep {
  private final ConsoleUI ui;
  private final Section gitweb;
  private final FileBasedConfig cfg;
  private final File gitilesConfig;

  @Inject
  InitGitiles(InitFlags flags, ConsoleUI ui, Section.Factory sections,
      SitePaths sitePaths) {
    this.ui = ui;
    this.gitweb = sections.get("gitweb", null);
    this.cfg = flags.cfg;
    this.gitilesConfig = new File(sitePaths.etc_dir, "gitiles.config");
  }

  @Override
  public void run() throws IOException {
    ui.header("Gitiles");
    if (!confirm()) {
      return;
    }

    gitweb.set("type", "custom");
    gitweb.set("linkname", "gitiles");
    gitweb.unset("cgi");
    gitweb.unset("pathSeparator");
    gitweb.set("url", "plugins/gitiles/");
    gitweb.set("revision", "${project}/+/${commit}");
    gitweb.set("project", "${project}");
    gitweb.set("branch", "${project}/+/${branch}");
    gitweb.set("filehistory", "${project}/+log/${branch}/${file}");

    // Configuration is mainly done in code. Create an empty config file so the
    // user knows where to put additional configuration.
    gitilesConfig.createNewFile();
  }

  private boolean confirm() {
    if (!cfg.getSections().contains("gitweb")) {
      return ui.yesno(true, "Configure Gitiles source browser");
    }
    if ("custom".equalsIgnoreCase(cfg.getString("gitweb", null, "type"))
        && "gitiles".equalsIgnoreCase(cfg.getString("gitweb", null, "linkname"))) {
      return ui.yesno(false, "Restore default Gitiles config");
    }
    return ui.yesno(false, "Override existing gitweb config with Gitiles");
  }
}
