// Copyright (C) 2016 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 com.google.gerrit.common.FileUtil.chmod;
import static com.google.gerrit.pgm.init.api.InitUtil.die;
import static com.google.gerrit.pgm.init.api.InitUtil.extract;
import static com.google.gerrit.pgm.init.api.InitUtil.mkdir;
import static com.google.gerrit.pgm.init.api.InitUtil.savePublic;
import static com.google.gerrit.pgm.init.api.InitUtil.version;

import com.google.gerrit.common.FileUtil;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.Section;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.mail.EmailModule;
import com.google.inject.Binding;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/** Initialize (or upgrade) an existing site. */
public class SitePathInitializer {
  private final ConsoleUI ui;
  private final InitFlags flags;
  private final SitePaths site;
  private final List<InitStep> steps;
  private final Section.Factory sectionFactory;
  private final SecureStoreInitData secureStoreInitData;

  @Inject
  public SitePathInitializer(
      final Injector injector,
      final ConsoleUI ui,
      final InitFlags flags,
      final SitePaths site,
      final Section.Factory sectionFactory,
      @Nullable final SecureStoreInitData secureStoreInitData) {
    this.ui = ui;
    this.flags = flags;
    this.site = site;
    this.sectionFactory = sectionFactory;
    this.secureStoreInitData = secureStoreInitData;
    this.steps = stepsOf(injector);
  }

  public void run() throws Exception {
    ui.header("Gerrit Code Review %s", version());

    if (site.isNew) {
      if (!ui.yesno(true, "Create '%s'", site.site_path.toAbsolutePath())) {
        throw die("aborted by user");
      }
      FileUtil.mkdirsOrDie(site.site_path, "Cannot make directory");
      flags.deleteOnFailure = true;
    }

    mkdir(site.bin_dir);
    mkdir(site.etc_dir);
    mkdir(site.lib_dir);
    mkdir(site.tmp_dir);
    mkdir(site.logs_dir);
    mkdir(site.mail_dir);
    mkdir(site.static_dir);
    mkdir(site.plugins_dir);
    mkdir(site.data_dir);

    for (InitStep step : steps) {
      if (step instanceof InitPlugins && flags.skipPlugins) {
        continue;
      }
      step.run();
    }

    saveSecureStore();
    savePublic(flags.cfg);

    extract(site.gerrit_sh, getClass(), "gerrit.sh");
    chmod(0755, site.gerrit_sh);
    extract(site.gerrit_service, getClass(), "gerrit.service");
    chmod(0755, site.gerrit_service);
    extract(site.gerrit_socket, getClass(), "gerrit.socket");
    chmod(0755, site.gerrit_socket);
    chmod(0700, site.tmp_dir);

    extractMailExample("Abandoned.soy");
    extractMailExample("AbandonedHtml.soy");
    extractMailExample("AddKey.soy");
    extractMailExample("AddKeyHtml.soy");
    extractMailExample("AddToAttentionSet.soy");
    extractMailExample("AddToAttentionSetHtml.soy");
    extractMailExample("AuthTokenExpired.soy");
    extractMailExample("AuthTokenExpiredHtml.soy");
    extractMailExample("AuthTokenWillExpire.soy");
    extractMailExample("AuthTokenWillExpireHtml.soy");
    extractMailExample("AuthTokenUpdate.soy");
    extractMailExample("AuthTokenUpdateHtml.soy");
    extractMailExample("ChangeFooter.soy");
    extractMailExample("ChangeFooterHtml.soy");
    extractMailExample("ChangeSubject.soy");
    extractMailExample("Comment.soy");
    extractMailExample("CommentHtml.soy");
    extractMailExample("CommentFooter.soy");
    extractMailExample("CommentFooterHtml.soy");
    extractMailExample("DeleteKey.soy");
    extractMailExample("DeleteKeyHtml.soy");
    extractMailExample("DeleteReviewer.soy");
    extractMailExample("DeleteReviewerHtml.soy");
    extractMailExample("DeleteVote.soy");
    extractMailExample("DeleteVoteHtml.soy");
    extractMailExample("Email.soy");
    extractMailExample("EmailHtml.soy");
    extractMailExample("Footer.soy");
    extractMailExample("FooterHtml.soy");
    extractMailExample("ChangeHeader.soy");
    extractMailExample("ChangeHeaderHtml.soy");
    extractMailExample("HttpPasswordUpdate.soy");
    extractMailExample("HttpPasswordUpdateHtml.soy");
    extractMailExample("InboundEmailRejection.soy");
    extractMailExample("InboundEmailRejectionHtml.soy");
    extractMailExample("Merged.soy");
    extractMailExample("MergedHtml.soy");
    extractMailExample("NewChange.soy");
    extractMailExample("NewChangeHtml.soy");
    extractMailExample("RegisterNewEmail.soy");
    extractMailExample("RegisterNewEmailHtml.soy");
    extractMailExample("RemoveFromAttentionSet.soy");
    extractMailExample("RemoveFromAttentionSetHtml.soy");
    extractMailExample("ReplacePatchSet.soy");
    extractMailExample("ReplacePatchSetHtml.soy");
    extractMailExample("Restored.soy");
    extractMailExample("RestoredHtml.soy");
    extractMailExample("Reverted.soy");
    extractMailExample("RevertedHtml.soy");

    if (!ui.isBatch()) {
      System.err.println();
    }
  }

  public void postRun(Injector injector) throws Exception {
    for (InitStep step : steps) {
      if (step instanceof InitPlugins && flags.skipPlugins) {
        continue;
      }
      injector.injectMembers(step);
      step.postRun();
    }
  }

  private void saveSecureStore() throws IOException {
    if (secureStoreInitData != null) {
      Path dst = site.lib_dir.resolve(secureStoreInitData.jarFile.getFileName());
      Files.copy(secureStoreInitData.jarFile, dst);
      Section gerritSection = sectionFactory.get("gerrit", null);
      gerritSection.set("secureStoreClass", secureStoreInitData.className);
    }
  }

  private void extractMailExample(String orig) throws Exception {
    Path ex = site.mail_dir.resolve(orig + ".example");
    extract(ex, EmailModule.class, orig);
    chmod(0444, ex);
  }

  private static List<InitStep> stepsOf(Injector injector) {
    final ArrayList<InitStep> r = new ArrayList<>();
    for (Binding<InitStep> b : all(injector)) {
      r.add(b.getProvider().get());
    }
    return r;
  }

  private static List<Binding<InitStep>> all(Injector injector) {
    return injector.findBindingsByType(new TypeLiteral<InitStep>() {});
  }
}
