/*
 * Copyright 2000-2015 JetBrains s.r.o.
 *
 * 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 jetbrains.buildServer.clouds.vmware.vmrun.remote.xmlrpc;

import com.thoughtworks.xstream.XStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Vector;
import jetbrains.buildServer.clouds.vmware.vmrun.remote.RemoteTask;
import jetbrains.buildServer.clouds.vmware.vmrun.remote.RemoteTaskResult;
import jetbrains.buildServer.clouds.vmware.vmrun.remote.VMRunServer;
import jetbrains.buildServer.messages.XStreamHolder;
import org.jetbrains.annotations.NotNull;

/**
 * @author Eugene Petrenko
 *         Created: 08.12.2009 14:00:48
 */
public class XmlRpcBasedVMRunServer implements XmlRpcVMRunServer{
  private final VMRunServer myHost;
  private final XStreamHolder myXStream;

  public XmlRpcBasedVMRunServer(final VMRunServer host, final XStreamHolder xStream) {
    myHost = host;
    myXStream = xStream;
  }

  public Vector<String> getTasks(@NotNull final String clientInfo) {
    final List<String> v = new WithXStream<List<String>>() {
      @Override
      protected List<String> action(@NotNull final XStream xs) {
        final Collection<RemoteTask> tasks = myHost.getTasks(clientInfo);
        List<String> v = new ArrayList<String>(tasks.size());
        for (RemoteTask task : tasks) {
          v.add(xs.toXML(task));
        }
        return v;
      }
    }.call();
    return new Vector<String>(v);
  }

  public Boolean postResults(@NotNull final String clientInfo, final Vector<String> result) {
    final List<RemoteTaskResult> rs = new WithXStream<List<RemoteTaskResult>>() {
      @Override
      protected List<RemoteTaskResult> action(@NotNull final XStream xs) {
        List<RemoteTaskResult> rs = new ArrayList<RemoteTaskResult>(result.size());
        for (String r : result) {
          rs.add((RemoteTaskResult)xs.fromXML(r));
        }
        return rs;
      }
    }.call();

    myHost.postResults(clientInfo, rs);

    return Boolean.TRUE;
  }

  //TODO: Move to XStreamHolder
  private abstract class WithXStream<T> {
    public T call() {
      final XStream xStream = myXStream.getXStream(getClass().getClassLoader());
      try {
        return action(xStream);
      } finally {
        myXStream.releaseXStream(xStream);
      }
    }

    protected abstract T action(@NotNull XStream xs);
  }
}
