// 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.its.bugzilla;

import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.pgm.init.api.AllProjectsConfig;
import com.google.gerrit.pgm.init.api.AllProjectsNameOnInitProvider;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.Section;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.googlesource.gerrit.plugins.hooks.its.InitIts;
import com.googlesource.gerrit.plugins.hooks.validation.ItsAssociationPolicy;
import com.j2bugzilla.base.BugzillaException;
import com.j2bugzilla.base.ConnectionException;

import org.eclipse.jgit.errors.ConfigInvalidException;

import java.io.IOException;
import java.util.Arrays;

/** Initialize the GitRepositoryManager configuration section. */
@Singleton
class InitBugzilla extends InitIts {
  private final String pluginName;
  private final Section.Factory sections;
  private final InitFlags flags;
  private Section bugzilla;
  private Section bugzillaComment;
  private String bugzillaUrl;
  private String bugzillaUsername;
  private String bugzillaPassword;

  @Inject
  InitBugzilla(@PluginName String pluginName, ConsoleUI ui,
      Section.Factory sections, AllProjectsConfig allProjectsConfig,
      AllProjectsNameOnInitProvider allProjects, InitFlags flags) {
    super(pluginName, "Bugzilla", ui, allProjectsConfig, allProjects);
    this.pluginName = pluginName;
    this.sections = sections;
    this.flags = flags;
  }

  @Override
  public void run() throws IOException, ConfigInvalidException {
    super.run();

    ui.message("\n");
    ui.header("Bugzilla connectivity");

    if (!pluginName.equalsIgnoreCase("bugzilla")
        && !flags.cfg.getSections().contains(pluginName)
        && flags.cfg.getSections().contains("bugzilla")) {
      ui.message("A Bugzilla configuration for the 'hooks-bugzilla' plugin was found.\n");
      if (ui.yesno(true, "Copy it for the '%s' plugin?", pluginName)) {
        for (String n : flags.cfg.getNames("bugzilla")) {
          flags.cfg.setStringList(pluginName, null, n,
              Arrays.asList(flags.cfg.getStringList("bugzilla", null, n)));
        }
        for (String n : flags.cfg.getNames(COMMENT_LINK_SECTION, "bugzilla")) {
          flags.cfg.setStringList(COMMENT_LINK_SECTION, pluginName, n,
              Arrays.asList(flags.cfg.getStringList(COMMENT_LINK_SECTION, "bugzilla", n)));
        }

        if (ui.yesno(false, "Remove configuration for 'hooks-bugzilla' plugin?")) {
          flags.cfg.unsetSection("bugzilla", null);
          flags.cfg.unsetSection(COMMENT_LINK_SECTION, "bugzilla");
        }
      } else {
        init();
      }
    } else {
      init();
    }
  }

  private void init() {
    this.bugzilla = sections.get(pluginName, null);
    this.bugzillaComment = sections.get(COMMENT_LINK_SECTION, pluginName);


    do {
      enterBugzillaConnectivity();
    } while (bugzillaUrl != null
        && (isConnectivityRequested(bugzillaUrl) && !isBugzillaConnectSuccessful()));

    if (bugzillaUrl == null) {
      return;
    }

    ui.header("Bugzilla issue-tracking association");
    bugzillaComment.string("Bugzilla bug number regex", "match", "\\([Bb][Uu][Gg][ ]*[1-9][0-9]*\\)");
    bugzillaComment.set("html",
        String.format("<a href=\"%s/show_bug.cgi?id=$1\">$1</a>", bugzillaUrl));
    bugzillaComment.select("Bug number enforced in commit message", "association",
        ItsAssociationPolicy.SUGGESTED);
  }

  public void enterBugzillaConnectivity() {
    bugzillaUrl = bugzilla.string("Bugzilla URL (empty to skip)", "url", null);
    if (bugzillaUrl != null) {
      bugzillaUsername = bugzilla.string("Bugzilla username", "username", "");
      bugzillaPassword = bugzilla.password("username", "password");
    }
  }

  private boolean isBugzillaConnectSuccessful() {
    ui.message("Checking Bugzilla connectivity ... ");
    try {
      BugzillaClient bugzillaClient = new BugzillaClient(bugzillaUrl);
      bugzillaClient.login(bugzillaUsername, bugzillaPassword);
      bugzillaClient.logout();
      ui.message("[OK]\n");
      return true;
    } catch (BugzillaException e) {
      ui.message("*FAILED* (%s)\n", e.toString());
      return false;
    } catch (ConnectionException e) {
      ui.message("*FAILED* (%s)\n", e.toString());
      return false;
    }
  }
}
