/*
 * Copyright (c) 2014, 2015 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.preferences.impl;

import org.eclipse.oomph.preferences.PreferenceNode;
import org.eclipse.oomph.preferences.PreferencesPackage;
import org.eclipse.oomph.preferences.Property;
import org.eclipse.oomph.preferences.util.PreferencesUtil;
import org.eclipse.oomph.util.IOExceptionWithCause;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.URIHandlerImpl;
import org.eclipse.emf.ecore.util.EcoreUtil.Copier;

import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.equinox.security.storage.StorageException;

import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

/**
 * @author Ed Merks
 */
public class PreferencesURIHandlerImpl extends URIHandlerImpl
{
  private static final IEclipsePreferences ROOT = Platform.getPreferencesService().getRootNode();

  @Override
  public boolean canHandle(URI uri)
  {
    return "preference".equals(uri.scheme());
  }

  protected static class PreferenceAccessor
  {
    private final Preferences preferences;

    private final ISecurePreferences securePreferences;

    private final String key;

    private final boolean isEncrypted;

    public PreferenceAccessor(URI uri)
    {
      String[] segments = uri.segments();
      int last = segments.length - 1;

      if ("secure".equals(segments[0]))
      {
        ISecurePreferences node = PreferencesUtil.getSecurePreferences();
        for (int i = 1; i < last; ++i)
        {
          node = node.node(segments[i]);
        }

        preferences = null;
        securePreferences = node;

        isEncrypted = !"encrypted=false".equals(uri.query());
      }
      else
      {
        Preferences node = ROOT;
        for (int i = 0; i < last; ++i)
        {
          node = node.node(segments[i]);
        }
        preferences = node;
        securePreferences = null;
        isEncrypted = false;
      }

      key = segments[last];
    }

    public String get() throws IOException
    {
      try
      {
        return securePreferences == null ? preferences.get(key, null) : securePreferences.get(key, null);
      }
      catch (StorageException ex)
      {
        throw new IOExceptionWithCause(ex);
      }
    }

    public void put(String value) throws IOException
    {
      if (securePreferences == null)
      {
        preferences.put(key, value);
      }
      else
      {
        try
        {
          boolean encrypt = isEncrypted;
          for (String key : securePreferences.keys())
          {
            if (key.equals(this.key))
            {
              encrypt = securePreferences.isEncrypted(key);
              break;
            }
          }

          securePreferences.put(key, value, encrypt);
        }
        catch (StorageException ex)
        {
          throw new IOExceptionWithCause(ex);
        }
      }

      flush();
    }

    public void remove() throws IOException
    {
      if (securePreferences == null)
      {
        preferences.remove(key);
      }
      else
      {
        securePreferences.remove(key);
      }

      flush();
    }

    private void flush() throws IOException
    {
      try
      {
        if (securePreferences == null)
        {
          preferences.flush();
        }
        else
        {
          securePreferences.flush();
        }
      }
      catch (BackingStoreException ex)
      {
        throw new IOExceptionWithCause(ex);
      }
    }
  }

  @Override
  public InputStream createInputStream(URI uri, final Map<?, ?> options) throws IOException
  {
    if (uri.segmentCount() == 1)
    {
      class PreferencesInput extends InputStream implements URIConverter.Loadable
      {
        private PreferenceNode preferencesNode = PreferencesUtil
            .getRootPreferenceNode(Boolean.TRUE.equals(options.get(PreferencesUtil.OPTION_SYNCHRONIZED_PREFERENCES)));

        private InputStream in;

        public void loadResource(Resource resource) throws IOException
        {
          resource.getContents().add(preferencesNode);
        }

        @Override
        public int read() throws IOException
        {
          if (in == null)
          {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            preferencesNode.eResource().save(out, null);
            in = new ByteArrayInputStream(out.toByteArray());
          }
          return in.read();
        }
      }

      return new PreferencesInput();
    }

    URI preferencePath = uri.trimSegments(1);
    String value = new PreferenceAccessor(preferencePath).get();
    if (value == null)
    {
      throw new IOException("No preference value available for " + preferencePath);
    }
    return new URIConverter.ReadableInputStream(value);
  }

  @Override
  public OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException
  {
    if (uri.segmentCount() == 1)
    {
      class PreferencesOutput extends OutputStream implements URIConverter.Saveable
      {
        public void saveResource(Resource resource) throws IOException
        {
          Copier copier = new Copier()
          {
            private static final long serialVersionUID = 1L;

            @Override
            protected void copyAttribute(EAttribute eAttribute, EObject eObject, EObject copyEObject)
            {
              if (eAttribute == PreferencesPackage.Literals.PROPERTY__VALUE)
              {
                Property property = (Property)eObject;
                Property copyProperty = (Property)copyEObject;
                copyProperty.setValue(property.getSecureValue());
              }
              else
              {
                super.copyAttribute(eAttribute, eObject, copyEObject);
              }
            }
          };
          PreferenceNode root = (PreferenceNode)copier.copy(resource.getContents().get(0));
          copier.copyReferences();

          Throwable throwable = null;
          try
          {
            Collection<? extends IEclipsePreferences> flush = PreferencesUtil.reconcile(root);
            for (IEclipsePreferences preferences : flush)
            {
              try
              {
                preferences.flush();
              }
              catch (Throwable ex)
              {
                throwable = ex;
              }
            }
          }
          catch (Throwable ex)
          {
            IOException ioException = new IOException(ex.getMessage());
            ioException.initCause(ex);
            throw ioException;
          }

          if (throwable != null)
          {
            IOException ioException = new IOException(throwable.getMessage());
            ioException.initCause(throwable);
            throw ioException;
          }
        }

        @Override
        public void write(int b) throws IOException
        {
          throw new IOException("Streamed output not supported");
        }
      }

      return new PreferencesOutput();
    }

    final PreferenceAccessor accessor = new PreferenceAccessor(uri.trimSegments(1));
    return new URIConverter.WriteableOutputStream(new StringWriter()
    {
      @Override
      public void close() throws IOException
      {
        super.close();
        accessor.put(toString());
      }
    }, "UTF-8");
  }

  @Override
  public void delete(URI uri, Map<?, ?> options) throws IOException
  {
    new PreferenceAccessor(uri.trimSegments(1)).remove();
  }

  @Override
  public boolean exists(URI uri, Map<?, ?> options)
  {
    try
    {
      return new PreferenceAccessor(uri.trimSegments(1)).get() != null;
    }
    catch (IOException ex)
    {
      return false;
    }
  }

  @Override
  public Map<String, ?> getAttributes(URI uri, Map<?, ?> options)
  {
    return Collections.emptyMap();
  }

  @Override
  public void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException
  {
    // Do nothing.
  }
}
