// 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 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;

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;

@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.data_dir.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 {
    InputStream resin = openPropertiesFile();
    try {
      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());
      }
    } finally {
      resin.close();
    }
  }

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

  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;
  }
}
