/*
 * Copyright (c) 2010-2012, 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.emf.cdo.util;

import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.eresource.CDOResource;

import org.eclipse.net4j.util.security.IUserManager;

import org.eclipse.emf.common.util.URI;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

import java.util.Map;
import java.util.Map.Entry;

/**
 * Represents a CDO-specific {@link URI} in connection-aware format.
 * <p>
 * CDO URIs are in one of two different formats, either canonical or connection-aware. The connection-aware format is:
 *
 * <blockquote><b>cdo.net4j.</b> <i>ConnectorType</i> <b>://</b> [<i>User</i> [<b>:</b> <i>Password</i>] <b>@</b>]
 * <i>ConnectorSpecificAuthority</i> <b>/</b> <i>RepositoryName</i> <b>/</b> <i>ResourcePath</i> [<b>?</b> <i>Param</i><b>=</b><i>Value</i>
 * (<b>&</b> <i>Param</i><b>=</b><i>Value</i>)*]</blockquote>
 *
 * The non-terminals being:
 * <p>
 * <ul>
 * <li><i>ConnectorType</i>: one of <b>tcp</b> | <b>ssl</b> | <b>jvm</b> | <b>http</b>
 * <li><i>User/Password</i>: to be provided if the repository is configured with an
 * {@link IUserManager} and, hence, triggers authentication on the client. Note: the
 * password may be stored in resources in clear text!
 * <li><i>ConnectorSpecificAuthority</i>: examples are
 * <ul>
 * <li><i>Host</i> [<b>:</b> <i>Port</i>] (if <i>ConnectorType</i> is <b>tcp</b>)
 * <li><i>AcceptorName</i> (if <i>ConnectorType</i> is <b>jvm</b>)
 * </ul>
 * <li><i>RepositoryName</i>: the {@link CDOCommonRepository#getName() name} of the repository (not the {@link CDOCommonRepository#getUUID() UUID}!).
 * <li><i>ResourcePath</i>: the full path of the {@link CDOResource resource} within the repository, segments separated by slashes, no leading slash.
 * <li><i>Param</i>: one of the following
 * <ul>
 * <li><b>branch</b>: the value must be a {@link CDOBranch#getPathName() branch path}, the full path of the branch in the branch tree, segments separated by slashes, no leading slash, defaults to <b>MAIN</b>.
 * <li><b>time</b>: the value must be the time at which the resource is supposed to be valid, parseable by SimpleDateFormat. The special value <b>HEAD</b> indicates a floating view/transaction that always shows the latest state in the chosen branch, the default if no <i>Time</i> parameter is specified.
 * <li><b>transactional</b>: a boolean value. The value <b>true</b> forces a the resource to be opened in a transaction rather than in a read-only view. This can not be combined with a <i>Time</i> other than <b>HEAD</b>.
 * <li><b>prefetch</b>: a boolean value. The value <b>true</b> attempts to load all objects contained by the resource in a single server-round trip and cache the results.
 * </ul>
 * </ul>
 * <p>
 * Note: With the current design and implementation of connection-aware URI
 * (mainly CDONet4jViewProvider) it is still unclear when and how the allocated
 * "resources" (aka IConnector, CDOSession, CDOView, etc) are supposed to be freed!
 * <p>
 * For a description of the canonical URI format refer to {@link CDOURIUtil}.
 *
 * @author Eike Stepper
 * @since 4.0
 */
public final class CDOURIData
{
  public static final String BRANCH_PARAMETER = "branch";

  public static final String TIME_PARAMETER = "time";

  /**
   * @since 4.1
   */
  public static final String VIEW_ID_PARAMETER = "view";

  public static final String TRANSACTIONAL_PARAMETER = "transactional";

  private String scheme;

  private String userName;

  private String passWord;

  private String authority;

  private String repositoryName;

  private IPath resourcePath;

  private IPath branchPath = new Path(CDOBranch.MAIN_BRANCH_NAME);

  private long timeStamp = CDOBranchPoint.UNSPECIFIED_DATE;

  private String viewID;

  private boolean transactional;

  private Map<String, String> extraParameters;

  public CDOURIData()
  {
  }

  public CDOURIData(String uri) throws InvalidURIException
  {
    this(URI.createURI(uri));
  }

  public CDOURIData(URI uri) throws InvalidURIException
  {
    try
    {
      scheme = uri.scheme();
      authority = uri.authority();
      String userInfo = uri.userInfo();
      if (userInfo != null)
      {
        authority = authority.substring(userInfo.length() + 1);
        int colon = userInfo.indexOf(':');
        if (colon != -1)
        {
          userName = userInfo.substring(0, colon);
          passWord = userInfo.substring(colon + 1);
        }
        else
        {
          userName = userInfo;
        }
      }

      IPath path = new Path(uri.path()).makeAbsolute();
      repositoryName = path.segment(0);
      resourcePath = path.removeFirstSegments(1);
      if (resourcePath == null || resourcePath.isEmpty())
      {
        resourcePath = new Path(CDOURIUtil.SEGMENT_SEPARATOR);
      }

      String query = uri.query();
      if (query != null && query.length() != 0)
      {
        Map<String, String> parameters = CDOURIUtil.getParameters(query);
        String branch = parameters.remove(BRANCH_PARAMETER);
        if (branch != null)
        {
          branchPath = new Path(branch).makeRelative();
        }

        String time = parameters.remove(TIME_PARAMETER);
        if (time != null)
        {
          if (!"HEAD".equalsIgnoreCase(time))
          {
            timeStamp = Long.parseLong(time);
          }
        }

        viewID = parameters.remove(VIEW_ID_PARAMETER);

        String transactional = parameters.remove(TRANSACTIONAL_PARAMETER);
        if (transactional != null)
        {
          this.transactional = Boolean.parseBoolean(transactional);
        }

        if (!parameters.isEmpty())
        {
          extraParameters = parameters;
        }
      }

      if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE && transactional)
      {
        throw new IllegalArgumentException("Only HEAD can be transactional");
      }
    }
    catch (Throwable t)
    {
      throw new InvalidURIException(uri, t);
    }

    // branchPath = Path.EMPTY.makeAbsolute();
    // timeStamp = CDOBranchPoint.UNSPECIFIED_DATE;
    //
    // while (resourcePath.segmentCount() != 0)
    // {
    // String segment = resourcePath.segment(0);
    // resourcePath = resourcePath.removeFirstSegments(1);
    //
    // if (segment.startsWith("@"))
    // {
    // if (segment.length() != 1)
    // {
    // if (!segment.equals("@HEAD"))
    // {
    // timeStamp = Long.parseLong(segment.substring(1));
    // }
    // }
    //
    // break;
    // }
    //
    // branchPath = branchPath.append(segment);
    // }
    //
    // int segments = branchPath.segmentCount();
    // if (segments == 0 || segments == 1 && !branchPath.segment(0).equals(CDOBranch.MAIN_BRANCH_NAME))
    // {
    // branchPath = new Path(CDOBranch.MAIN_BRANCH_NAME).append(branchPath);
    // }
  }

  public String getScheme()
  {
    return scheme;
  }

  public void setScheme(String scheme)
  {
    this.scheme = scheme;
  }

  public String getUserName()
  {
    return userName;
  }

  public void setUserName(String userName)
  {
    this.userName = userName;
  }

  public String getPassWord()
  {
    return passWord;
  }

  public void setPassWord(String passWord)
  {
    this.passWord = passWord;
  }

  public String getAuthority()
  {
    return authority;
  }

  public void setAuthority(String authority)
  {
    this.authority = authority;
  }

  public String getRepositoryName()
  {
    return repositoryName;
  }

  public void setRepositoryName(String repositoryName)
  {
    this.repositoryName = repositoryName;
  }

  public IPath getResourcePath()
  {
    return resourcePath;
  }

  public void setResourcePath(IPath resourcePath)
  {
    this.resourcePath = resourcePath;
  }

  public IPath getBranchPath()
  {
    return branchPath;
  }

  public void setBranchPath(IPath branchPath)
  {
    this.branchPath = branchPath;
  }

  public long getTimeStamp()
  {
    return timeStamp;
  }

  public void setTimeStamp(long timeStamp)
  {
    this.timeStamp = timeStamp;
  }

  /**
   * @since 4.1
   */
  public String getViewID()
  {
    return viewID;
  }

  /**
   * @since 4.1
   */
  public void setViewID(String viewID)
  {
    this.viewID = viewID;
  }

  public boolean isTransactional()
  {
    return transactional;
  }

  public void setTransactional(boolean transactional)
  {
    this.transactional = transactional;
  }

  /**
   * @since 4.1
   */
  public Map<String, String> getExtraParameters()
  {
    return extraParameters;
  }

  /**
   * @since 4.4
   */
  public void setExtraParameters(Map<String, String> extraParameters)
  {
    this.extraParameters = extraParameters;
  }

  public URI toURI()
  {
    return URI.createURI(toString());
  }

  @Override
  public String toString()
  {
    StringBuilder builder = new StringBuilder();
    builder.append(scheme);
    builder.append("://");
    if (userName != null)
    {
      builder.append(userName);
      if (passWord != null)
      {
        builder.append(":");
        builder.append(passWord);
      }

      builder.append("@");
    }

    builder.append(authority);
    builder.append("/");
    builder.append(repositoryName);

    if (resourcePath != null)
    {
      builder.append("/");
      builder.append(resourcePath);
    }

    int params = 0;
    if (branchPath != null && !branchPath.equals(new Path(CDOBranch.MAIN_BRANCH_NAME)))
    {
      builder.append(params++ == 0 ? "?" : "&");
      builder.append(BRANCH_PARAMETER);
      builder.append("=");
      builder.append(branchPath.toPortableString());
    }

    if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
    {
      builder.append(params++ == 0 ? "?" : "&");
      builder.append(TIME_PARAMETER);
      builder.append("=");
      builder.append(timeStamp);
    }

    if (viewID != null)
    {
      builder.append(params++ == 0 ? "?" : "&");
      builder.append(VIEW_ID_PARAMETER);
      builder.append("=");
      builder.append(viewID);
    }

    if (transactional)
    {
      builder.append(params++ == 0 ? "?" : "&");
      builder.append(TRANSACTIONAL_PARAMETER);
      builder.append("=");
      builder.append(transactional);
    }

    if (extraParameters != null)
    {
      for (Entry<String, String> entry : extraParameters.entrySet())
      {
        builder.append(params++ == 0 ? "?" : "&");
        builder.append(entry.getKey());
        builder.append("=");
        builder.append(entry.getValue());
      }
    }

    return builder.toString();
  }
}
