// Copyright (C) 2014 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.gitblit.app;

import com.gitblit.IStoredSettings;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.gitblit.GitBlitUrlsConfig;
import com.googlesource.gerrit.plugins.gitblit.auth.GerritToGitBlitUserService;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class GitBlitSettings extends IStoredSettings {
  private static final Logger log = LoggerFactory.getLogger(GitBlitSettings.class);
  private static final String GITBLIT_GERRIT_PROPERTIES = "/gitblit.properties";

  private final GitBlitUrlsConfig config;
  private final File etcDir;
  private final File basePath;

  private Properties properties;
  private File gitblitPropertiesFile;

  @Inject
  public GitBlitSettings(@GerritServerConfig Config config, SitePaths sitePaths)
      throws IOException {
    super(GitBlitSettings.class);
    this.properties = new Properties();
    this.config = new GitBlitUrlsConfig(config);
    this.etcDir = sitePaths.etc_dir.toFile();
    this.basePath = sitePaths.resolve(config.getString("gerrit", null, "basePath")).toFile();
    load();
  }

  @Override
  protected Properties read() {
    return properties;
  }

  @Override
  public boolean saveSettings(Map<String, String> updatedSettings) {
    properties.putAll(updatedSettings);
    return true;
  }

  private void load() throws IOException {
    try (InputStream resin = openPropertiesFile()) {
      properties = new Properties();
      properties.load(resin);
      properties.put("git.repositoriesFolder", getBasePath().getAbsolutePath());
      properties.put("realm.userService", GerritToGitBlitUserService.class.getName());
      if (properties.get("web.otherUrls") != null) {
        properties.put(
            "web.otherUrls",
            (config.getGitHttpUrl() + " " + config.getGitSshUrl()).trim()
                + " "
                + properties.get("web.otherUrls"));
      } else {
        properties.put(
            "web.otherUrls", (config.getGitHttpUrl() + " " + config.getGitSshUrl()).trim());
      }
    }
  }

  private InputStream openPropertiesFile() {
    gitblitPropertiesFile = new File(etcDir, GITBLIT_GERRIT_PROPERTIES);
    if (gitblitPropertiesFile.exists()) {
      try {
        return new FileInputStream(gitblitPropertiesFile);
      } catch (FileNotFoundException e) {
        // this would never happen as we checked for file existence before
        throw new IllegalStateException(e);
      }
    }
    return getClass().getResourceAsStream(GITBLIT_GERRIT_PROPERTIES);
  }

  public File getBasePath() {
    return basePath;
  }

  @Override
  public String toString() {
    StringBuilder stringSettings = new StringBuilder();
    if (!gitblitPropertiesFile.exists()) {
      stringSettings.append(GITBLIT_GERRIT_PROPERTIES + " from gitblit plugin jar");
    } else {
      stringSettings.append(
          gitblitPropertiesFile.getAbsolutePath()
              + " (lastModified: "
              + new SimpleDateFormat().format(new Date(gitblitPropertiesFile.lastModified()))
              + ")");
    }

    stringSettings.append(" with values ");
    stringSettings.append(properties.toString());
    return stringSettings.toString();
  }

  @Override
  public boolean saveSettings() {
    log.warn("Store of GitBlit settings is not supported");
    return false;
  }
}
