// 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.google.gerrit.server.account;

import static com.google.gerrit.server.account.GetPreferences.KEY_ID;
import static com.google.gerrit.server.account.GetPreferences.KEY_TARGET;
import static com.google.gerrit.server.account.GetPreferences.KEY_URL;
import static com.google.gerrit.server.account.GetPreferences.MY;

import com.google.common.base.Strings;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.TopMenu;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.ChangeScreen;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.CommentVisibilityStrategy;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.ReviewCategoryStrategy;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DateFormat;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DiffView;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.TimeFormat;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.SetPreferences.Input;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

@Singleton
public class SetPreferences implements RestModifyView<AccountResource, Input> {
  public static class Input {
    public Short changesPerPage;
    public Boolean showSiteHeader;
    public Boolean useFlashClipboard;
    public DownloadScheme downloadScheme;
    public DownloadCommand downloadCommand;
    public Boolean copySelfOnEmail;
    public DateFormat dateFormat;
    public TimeFormat timeFormat;
    public Boolean reversePatchSetOrder;
    public Boolean relativeDateInChangeTable;
    public Boolean sizeBarInChangeTable;
    public Boolean legacycidInChangeTable;
    public CommentVisibilityStrategy commentVisibilityStrategy;
    public ReviewCategoryStrategy reviewCategoryStrategy;
    public DiffView diffView;
    public ChangeScreen changeScreen;
    public List<TopMenu.MenuItem> my;
  }

  private final Provider<CurrentUser> self;
  private final AccountCache cache;
  private final Provider<ReviewDb> db;
  private final MetaDataUpdate.User metaDataUpdateFactory;
  private final AllUsersName allUsersName;

  @Inject
  SetPreferences(Provider<CurrentUser> self, AccountCache cache,
      Provider<ReviewDb> db, MetaDataUpdate.User metaDataUpdateFactory,
      AllUsersName allUsersName) {
    this.self = self;
    this.cache = cache;
    this.db = db;
    this.metaDataUpdateFactory = metaDataUpdateFactory;
    this.allUsersName = allUsersName;
  }

  @Override
  public GetPreferences.PreferenceInfo apply(AccountResource rsrc, Input i)
      throws AuthException, ResourceNotFoundException, OrmException,
      IOException, ConfigInvalidException {
    if (self.get() != rsrc.getUser()
        && !self.get().getCapabilities().canAdministrateServer()) {
      throw new AuthException("restricted to administrator");
    }
    if (i == null) {
      i = new Input();
    }

    Account.Id accountId = rsrc.getUser().getAccountId();
    AccountGeneralPreferences p;
    VersionedAccountPreferences versionedPrefs;
    MetaDataUpdate md = metaDataUpdateFactory.create(allUsersName);
    db.get().accounts().beginTransaction(accountId);
    try {
      Account a = db.get().accounts().get(accountId);
      if (a == null) {
        throw new ResourceNotFoundException();
      }

      versionedPrefs = VersionedAccountPreferences.forUser(accountId);
      versionedPrefs.load(md);

      p = a.getGeneralPreferences();
      if (p == null) {
        p = new AccountGeneralPreferences();
        a.setGeneralPreferences(p);
      }

      if (i.changesPerPage != null) {
        p.setMaximumPageSize(i.changesPerPage);
      }
      if (i.showSiteHeader != null) {
        p.setShowSiteHeader(i.showSiteHeader);
      }
      if (i.useFlashClipboard != null) {
        p.setUseFlashClipboard(i.useFlashClipboard);
      }
      if (i.downloadScheme != null) {
        p.setDownloadUrl(i.downloadScheme);
      }
      if (i.downloadCommand != null) {
        p.setDownloadCommand(i.downloadCommand);
      }
      if (i.copySelfOnEmail != null) {
        p.setCopySelfOnEmails(i.copySelfOnEmail);
      }
      if (i.dateFormat != null) {
        p.setDateFormat(i.dateFormat);
      }
      if (i.timeFormat != null) {
        p.setTimeFormat(i.timeFormat);
      }
      if (i.reversePatchSetOrder != null) {
        p.setReversePatchSetOrder(i.reversePatchSetOrder);
      }
      if (i.relativeDateInChangeTable != null) {
        p.setRelativeDateInChangeTable(i.relativeDateInChangeTable);
      }
      if (i.sizeBarInChangeTable != null) {
        p.setSizeBarInChangeTable(i.sizeBarInChangeTable);
      }
      if (i.legacycidInChangeTable != null) {
        p.setLegacycidInChangeTable(i.legacycidInChangeTable);
      }
      if (i.reviewCategoryStrategy != null) {
        p.setReviewCategoryStrategy(i.reviewCategoryStrategy);
      }
      if (i.commentVisibilityStrategy != null) {
        p.setCommentVisibilityStrategy(i.commentVisibilityStrategy);
      }
      if (i.diffView != null) {
        p.setDiffView(i.diffView);
      }
      if (i.changeScreen != null) {
        p.setChangeScreen(i.changeScreen);
      }

      db.get().accounts().update(Collections.singleton(a));
      db.get().commit();
      storeMyMenus(versionedPrefs, i.my);
      versionedPrefs.commit(md);
      cache.evict(accountId);
      return new GetPreferences.PreferenceInfo(
          p, versionedPrefs,
          md.getRepository());
    } finally {
      md.close();
      db.get().rollback();
    }
  }

  public static void storeMyMenus(VersionedAccountPreferences prefs,
      List<TopMenu.MenuItem> my) {
    Config cfg = prefs.getConfig();
    if (my != null) {
      unsetSection(cfg, MY);
      for (TopMenu.MenuItem item : my) {
        set(cfg, item.name, KEY_URL, item.url);
        set(cfg, item.name, KEY_TARGET, item.target);
        set(cfg, item.name, KEY_ID, item.id);
      }
    }
  }

  private static void set(Config cfg, String section, String key, String val) {
    if (Strings.isNullOrEmpty(val)) {
      cfg.unset(MY, section, key);
    } else {
      cfg.setString(MY, section, key, val);
    }
  }

  private static void unsetSection(Config cfg, String section) {
    cfg.unsetSection(section, null);
    for (String subsection: cfg.getSubsections(section)) {
      cfg.unsetSection(section, subsection);
    }
  }
}
