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

import org.eclipse.userstorage.IBlob;
import org.eclipse.userstorage.IStorage;
import org.eclipse.userstorage.IStorageService;
import org.eclipse.userstorage.StorageFactory;
import org.eclipse.userstorage.internal.util.IOUtil.TeeInputStream;
import org.eclipse.userstorage.internal.util.StringUtil;
import org.eclipse.userstorage.spi.ISettings;
import org.eclipse.userstorage.spi.StorageCache;
import org.eclipse.userstorage.util.BadApplicationTokenException;
import org.eclipse.userstorage.util.ConflictException;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * @author Eike Stepper
 */
public final class Storage implements IStorage
{
  private final String applicationToken;

  private final StorageFactory factory;

  private final InternalStorageCache cache;

  private final Map<String, Blob> blobs = new WeakHashMap<String, Blob>();

  private StorageService service;

  public Storage(StorageFactory factory, String applicationToken, InternalStorageCache cache) throws BadApplicationTokenException
  {
    this.applicationToken = BadApplicationTokenException.validate(applicationToken);
    this.factory = factory;
    this.cache = cache;
  }

  @Override
  public String getApplicationToken()
  {
    return applicationToken;
  }

  @Override
  public StorageCache getCache()
  {
    return (StorageCache)cache;
  }

  @Override
  public StorageService getService()
  {
    return service;
  }

  @Override
  public synchronized void setService(IStorageService service)
  {
    if (service != this.service)
    {
      disposeBlobs();

      this.service = (StorageService)service;
      setPreferredServiceURI(service.getServiceURI().toString());

      if (cache != null)
      {
        cache.setService(service);
      }
    }
  }

  @Override
  public synchronized IBlob getBlob(String key)
  {
    Blob blob = blobs.get(key);
    if (blob == null)
    {
      Map<String, String> properties = new HashMap<String, String>();

      if (cache != null)
      {
        try
        {
          cache.internalLoadProperties(applicationToken, key, properties);
        }
        catch (IOException ex)
        {
          properties.clear();
          Activator.log(ex);
        }
      }

      blob = new Blob(this, key, properties);
      blobs.put(key, blob);
    }

    return blob;
  }

  public void setETag(String key, Map<String, String> properties, String eTag)
  {
    if (StringUtil.isEmpty(eTag))
    {
      properties.remove(Blob.ETAG);
    }
    else
    {
      properties.put(Blob.ETAG, eTag);
    }

    if (cache != null)
    {
      try
      {
        if (!StringUtil.isEmpty(eTag))
        {
          Map<String, String> cacheProperties = new HashMap<String, String>();
          cache.loadProperties(applicationToken, key, cacheProperties);
          String cacheETag = cacheProperties.get(Blob.ETAG);
          if (eTag.equals(cacheETag))
          {
            // Don't delete blob from cache because it has the new ETag.
            return;
          }
        }

        cache.internalDelete(applicationToken, key);
      }
      catch (IOException ex)
      {
        Activator.log(ex);
      }
    }
  }

  public InputStream retrieveBlob(String key, Map<String, String> properties) throws IOException
  {
    InputStream contents = service.retrieveBlob(applicationToken, key, properties, cache != null);

    if (cache != null)
    {
      if (contents == Blob.NOT_MODIFIED)
      {
        return cache.internalGetInputStream(applicationToken, key);
      }

      if (contents == null)
      {
        cache.internalDelete(applicationToken, key);
        return null;
      }

      OutputStream output = cache.internalGetOutputStream(applicationToken, key, properties);
      return new TeeInputStream(contents, output);
    }

    return contents;
  }

  public boolean updateBlob(String key, Map<String, String> properties, InputStream in) throws IOException, ConflictException
  {
    if (cache != null)
    {
      OutputStream output = cache.internalGetOutputStream(applicationToken, key, properties);
      in = new TeeInputStream(in, output);
    }

    boolean created = service.updateBlob(applicationToken, key, properties, in);

    if (cache != null)
    {
      cache.internalSaveProperties(applicationToken, key, properties);
    }

    return created;
  }

  @Override
  public String toString()
  {
    return service + " (" + applicationToken + ")";
  }

  private void setPreferredServiceURI(String serviceURI)
  {
    try
    {
      ISettings settings = factory.getSettings();
      settings.setValue(applicationToken, serviceURI);
    }
    catch (Exception ex)
    {
      Activator.log(ex);
    }
  }

  private void disposeBlobs()
  {
    for (Blob blob : blobs.values())
    {
      blob.dispose();
    }

    blobs.clear();

    if (cache != null)
    {
      try
      {
        for (Iterator<String> it = cache.getKeys(applicationToken); it.hasNext();)
        {
          String key = it.next();

          try
          {
            cache.delete(applicationToken, key);
          }
          catch (Exception ex)
          {
            Activator.log(ex);
          }
        }
      }
      catch (Exception ex)
      {
        Activator.log(ex);
      }
    }
  }
}
