/*
 * Copyright (c) 2015 Eike Stepper (Berlin, Germany) and others.
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.userstorage.ui.internal;

import org.eclipse.userstorage.IBlob;
import org.eclipse.userstorage.IStorage;
import org.eclipse.userstorage.IStorageService;
import org.eclipse.userstorage.IStorageService.Registry;
import org.eclipse.userstorage.StorageFactory;
import org.eclipse.userstorage.internal.StorageService;
import org.eclipse.userstorage.internal.util.StringUtil;
import org.eclipse.userstorage.spi.Credentials;
import org.eclipse.userstorage.ui.ServiceSelectorComposite;

import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author Eike Stepper
 */
public class ServicesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage
{
  public static final String ID = "org.eclipse.userstorage.ui.ServicesPreferencePage";

  private static final Registry REGISTRY = IStorageService.Registry.INSTANCE;

  private Map<IStorageService, Credentials> credentialsMap = new HashMap<IStorageService, Credentials>();

  private Map<IStorageService, Boolean> termsOfUseAgreedMap = new HashMap<IStorageService, Boolean>();

  private TableViewer servicesViewer;

  private CredentialsComposite credentialsComposite;

  private Button addButton;

  private Button removeButton;

  private Button testButton;

  private IStorageService selectedService;

  private boolean skipValidate;

  public ServicesPreferencePage()
  {
    super("User Storage Service");
  }

  @Override
  public void init(IWorkbench workbench)
  {
    // Do nothing.
  }

  @Override
  public void applyData(Object data)
  {
    if (data instanceof IStorageService)
    {
      IStorageService service = (IStorageService)data;
      setSelectedService(service);
    }
  }

  @Override
  public void createControl(Composite parent)
  {
    super.createControl(parent);
    updateEnablement();
  }

  @Override
  protected Control createContents(final Composite parent)
  {
    final ServicesContentProvider contentProvider = ServiceSelectorComposite.isShowServices() ? new ServicesContentProvider() : null;

    final Composite mainArea = createArea(parent, 2);
    mainArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    Composite leftArea = createArea(mainArea, 1);
    leftArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    if (contentProvider != null)
    {
      Label servicesLabel = new Label(leftArea, SWT.NONE);
      servicesLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
      servicesLabel.setText("Services:");

      TableColumnLayout tableLayout = new TableColumnLayout();
      Composite tableComposite = new Composite(leftArea, SWT.NONE);
      tableComposite.setLayout(tableLayout);
      tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

      servicesViewer = new TableViewer(tableComposite, SWT.BORDER);
      servicesViewer.setContentProvider(contentProvider);
      servicesViewer.setLabelProvider(new ServicesLabelProvider());
      servicesViewer.setInput(REGISTRY);
      servicesViewer.addSelectionChangedListener(new ISelectionChangedListener()
      {
        @Override
        public void selectionChanged(SelectionChangedEvent event)
        {
          IStructuredSelection selection = (IStructuredSelection)event.getSelection();
          setSelectedService((IStorageService)selection.getFirstElement());
        }
      });

      TableColumn tableColumn = new TableColumn(servicesViewer.getTable(), SWT.LEFT);
      tableLayout.setColumnData(tableColumn, new ColumnWeightData(100));

      new Label(leftArea, SWT.NONE);
    }

    credentialsComposite = new CredentialsComposite(leftArea, SWT.NONE, 0, 0, false)
    {
      @Override
      protected void validate()
      {
        if (selectedService != null && !skipValidate)
        {
          Credentials credentials = getCredentials();
          boolean termsOfUseAgreed = isTermsOfUseAgreed();
          update(credentials, termsOfUseAgreed);
        }
      }
    };

    credentialsComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

    if (contentProvider != null)
    {
      Composite rightArea = createArea(mainArea, 1);
      rightArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));

      new Label(rightArea, SWT.NONE);

      addButton = new Button(rightArea, SWT.NONE);
      addButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
      addButton.setText("Add...");
      addButton.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          AddServiceDialog dialog = new AddServiceDialog(getShell());
          if (dialog.open() == AddServiceDialog.OK)
          {
            String serviceLabel = dialog.getServiceLabel();
            URI serviceURI = dialog.getServiceURI();
            URI createAccountURI = dialog.getCreateAccountURI();
            URI editAccountURI = dialog.getEditAccountURI();
            URI recoverPasswordURI = dialog.getRecoverPasswordURI();
            String termsOfUseLink = dialog.getTermsOfUseLink();

            REGISTRY.addService(serviceLabel, serviceURI, createAccountURI, editAccountURI, recoverPasswordURI, termsOfUseLink);
          }
        }
      });

      removeButton = new Button(rightArea, SWT.NONE);
      removeButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
      removeButton.setText("Remove");
      removeButton.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          if (selectedService instanceof IStorageService.Dynamic)
          {
            IStorageService.Dynamic dynamicService = (IStorageService.Dynamic)selectedService;
            Object[] elements = contentProvider.getElements(null);
            final int currentIndex = getCurrentIndex(elements, dynamicService);

            if (MessageDialog.openQuestion(getShell(), "Remove Service",
                "Do you really want to remove the '" + dynamicService.getServiceLabel() + "' service?"))
            {
              dynamicService.remove();

              final Control control = servicesViewer.getControl();
              control.getDisplay().asyncExec(new Runnable()
              {
                @Override
                public void run()
                {
                  if (!control.isDisposed())
                  {
                    Object[] elements = contentProvider.getElements(null);
                    if (elements.length != 0)
                    {
                      int newIndex = currentIndex;
                      if (newIndex >= elements.length)
                      {
                        newIndex = elements.length - 1;
                      }

                      setSelectedService((IStorageService)elements[newIndex]);
                    }
                  }
                }
              });
            }
          }
        }

        private int getCurrentIndex(Object[] elements, IStorageService service)
        {
          for (int i = 0; i < elements.length; i++)
          {
            Object element = elements[i];
            if (element == service)
            {
              return i;
            }
          }

          return 0;
        }
      });

      Button refreshButton = new Button(rightArea, SWT.NONE);
      refreshButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
      refreshButton.setText("Refresh");
      refreshButton.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          REGISTRY.refresh();
        }
      });
    }

    Object[] elements = contentProvider == null ? REGISTRY.getServices() : contentProvider.getElements(null);
    if (elements.length != 0)
    {
      setSelectedService((IStorageService)elements[0]);
    }

    if (Boolean.getBoolean("org.eclipse.userstorage.ui.showTestButton"))
    {
      testButton = new Button(leftArea, SWT.PUSH);
      testButton.setText("Test");
      testButton.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          try
          {
            IStorage storage = StorageFactory.DEFAULT.create("pDKTqBfDuNxlAKydhEwxBZPxa4q");
            IBlob blob = storage.getBlob("ui_test");
            blob.setContentsUTF("Test 123");
            performDefaults();
            MessageDialog.openInformation(getShell(), "Test", "Test succeeded.");
          }
          catch (Exception ex)
          {
            performDefaults();
            ErrorDialog.openError(getShell(), "Test", "Test failed.", Activator.getStatus(ex));
          }
        }
      });
    }

    applyDialogFont(mainArea);
    return mainArea;
  }

  @Override
  protected void performDefaults()
  {
    credentialsMap.clear();
    termsOfUseAgreedMap.clear();

    try
    {
      skipValidate = true;

      IStorageService service = selectedService;
      selectedService = null;
      setSelectedService(service);
    }
    finally
    {
      skipValidate = false;
    }

    updateEnablement();
  }

  @Override
  protected Point doComputeSize()
  {
    return CredentialsComposite.INITIAL_SIZE;
  }

  @Override
  public boolean performOk()
  {
    for (Map.Entry<IStorageService, Credentials> entry : credentialsMap.entrySet())
    {
      IStorageService service = entry.getKey();
      Credentials credentials = entry.getValue();
      ((StorageService)service).setCredentials(credentials);
    }

    for (Entry<IStorageService, Boolean> entry : termsOfUseAgreedMap.entrySet())
    {
      IStorageService service = entry.getKey();
      Boolean termsOfUseAgreed = entry.getValue();
      ((StorageService)service).setTermsOfUseAgreed(Boolean.TRUE.equals(termsOfUseAgreed));
    }

    updateEnablement();
    return true;
  }

  private Composite createArea(Composite parent, int columns)
  {
    GridLayout layout = new GridLayout(columns, false);
    layout.marginWidth = 0;
    layout.marginHeight = 0;

    final Composite main = new Composite(parent, SWT.NONE);
    main.setLayout(layout);
    return main;
  }

  private void setSelectedService(IStorageService service)
  {
    if (service != selectedService)
    {
      selectedService = service;

      if (selectedService != null)
      {
        Credentials credentials = credentialsMap.get(selectedService);
        if (credentials == null)
        {
          credentials = ((StorageService)selectedService).getCredentials();
          if (credentials != null)
          {
            credentialsMap.put(selectedService, credentials);
          }
        }

        Boolean termsOfUseAgreed = termsOfUseAgreedMap.get(selectedService);
        if (termsOfUseAgreed == null)
        {
          termsOfUseAgreed = ((StorageService)selectedService).isTermsOfUseAgreed();
          termsOfUseAgreedMap.put(selectedService, termsOfUseAgreed);
        }

        try
        {
          skipValidate = true;

          credentialsComposite.setService(selectedService);
          credentialsComposite.setCredentials(credentials);
          credentialsComposite.setTermsOfUseAgreed(termsOfUseAgreed);
        }
        finally
        {
          skipValidate = false;
        }

        update(credentials, termsOfUseAgreed);

        if (removeButton != null)
        {
          removeButton.setEnabled(selectedService instanceof IStorageService.Dynamic);
        }

        if (servicesViewer != null)
        {
          servicesViewer.setSelection(new StructuredSelection(selectedService));
        }
      }
      else
      {
        credentialsComposite.setService(null);
        credentialsComposite.setCredentials(null);

        if (removeButton != null)
        {
          removeButton.setEnabled(false);
        }
      }
    }
  }

  private void update(Credentials credentials, boolean termsOfUseAgreed)
  {
    credentialsMap.put(selectedService, credentials);
    termsOfUseAgreedMap.put(selectedService, termsOfUseAgreed);
    updateEnablement();
  }

  private void updateEnablement()
  {
    boolean dirty = false;

    for (IStorageService service : REGISTRY.getServices())
    {
      Credentials localCredentials = credentialsMap.get(service);
      String localUsername = "";
      String localPassword = "";
      if (localCredentials != null)
      {
        localUsername = StringUtil.safe(localCredentials.getUsername());
        localPassword = StringUtil.safe(localCredentials.getPassword());
      }
      else
      {
        continue;
      }

      Credentials credentials = ((StorageService)service).getCredentials();
      String username = "";
      String password = "";
      if (credentials != null)
      {
        username = StringUtil.safe(credentials.getUsername());
        password = StringUtil.safe(credentials.getPassword());
      }

      if (!localUsername.equals(username) || !localPassword.equals(password))
      {
        dirty = true;
        break;
      }
    }

    if (!dirty)
    {
      for (IStorageService service : REGISTRY.getServices())
      {
        boolean localTermsOfUseAgreed = Boolean.TRUE.equals(termsOfUseAgreedMap.get(service));
        boolean termsOfUseAgreed = ((StorageService)service).isTermsOfUseAgreed();
        if (localTermsOfUseAgreed != termsOfUseAgreed)
        {
          dirty = true;
          break;
        }
      }
    }

    Button defaultsButton = getDefaultsButton();
    if (defaultsButton != null)
    {
      defaultsButton.setEnabled(dirty);
    }

    Button applyButton = getApplyButton();
    if (applyButton != null)
    {
      applyButton.setEnabled(dirty);
    }
  }
}
