/*
 * Copyright 2000-2009 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 com.intellij.execution.junit2.segments;

import com.intellij.execution.junit.SegmentedInputStreamReader;
import com.intellij.execution.junit2.SegmentedInputStream;
import com.intellij.execution.testframework.Printable;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.rt.execution.junit.segments.PacketProcessor;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;

import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;

/**
 * @author dyoma
 */
public class Extractor implements Disposable {
  private DeferredActionsQueue myFulfilledWorkGate = null;
  private final SegmentedInputStream myStream;
  private OutputPacketProcessor myEventsDispatcher;
  private static final Logger LOG = Logger.getInstance("#" + Extractor.class.getName());
  private final MergingUpdateQueue myQueue = new MergingUpdateQueue("Test Extractor", 20, true, MergingUpdateQueue.ANY_COMPONENT, this);

  public Extractor(@NotNull InputStream stream, @NotNull Charset charset) {
    myStream = new SegmentedInputStream(stream, charset);
    myQueue.setPassThrough(false);//should be updated in awt thread
  }

  @Override
  public void dispose() {
  }

  public void setDispatchListener(final DispatchListener listener) {
    myFulfilledWorkGate.setDispactchListener(listener);
  }

  public void setPacketDispatcher(final PacketProcessor packetProcessor, final DeferredActionsQueue queue) {
    myFulfilledWorkGate = new DeferredActionsQueue() { //todo make it all later
      @Override
      public void addLast(final Runnable runnable) {
        myQueue.queue(new Update(runnable) {
          @Override
          public void run() {
            queue.addLast(runnable);
          }
        });
      }

      @Override
      public void setDispactchListener(final DispatchListener listener) {
        queue.setDispactchListener(listener);
      }
    };
    myEventsDispatcher = new OutputPacketProcessor() {
      @Override
      public void processPacket(final String packet) {
        myFulfilledWorkGate.addLast(new Runnable() {
          @Override
          public void run() {
            packetProcessor.processPacket(packet);
          }
        });
      }

      @Override
      public void processOutput(final Printable printable) {
        LOG.assertTrue(packetProcessor instanceof OutputPacketProcessor);
        myFulfilledWorkGate.addLast(new Runnable() {
          @Override
          public void run() {
            ((OutputPacketProcessor)packetProcessor).processOutput(printable);
          }
        });
      }
    };
    myStream.setEventsDispatcher(myEventsDispatcher);
  }

  public OutputPacketProcessor getEventsDispatcher() {
    return myEventsDispatcher;
  }

  public Reader createReader() {
    return new SegmentedInputStreamReader(myStream);
  }

}

@@ -1654,16 +1654,44 @@
 , this);
+%0A  private int myOrder = -1;
 %0A%0A  publ
@@ -2348,16 +2348,18 @@
 eue(new 
+My
 Update(r
@@ -2369,120 +2369,27 @@
 able
-) %7B%0A          @Override%0A          public void run() %7B%0A            queue.addLast(runnable);%0A          %7D%0A        %7D
+, queue, myOrder++)
 );%0A 
@@ -3473,10 +3473,550 @@
 );%0A  %7D%0A%0A
+  private static class MyUpdate extends Update %7B%0A    private final Runnable myRunnable;%0A    private final DeferredActionsQueue myQueue;%0A    private final int myOrder;%0A%0A    public MyUpdate(Runnable runnable, DeferredActionsQueue queue, int order) %7B%0A      super(runnable);%0A      myRunnable = runnable;%0A      myQueue = queue;%0A      myOrder = order;%0A    %7D%0A%0A    @Override%0A    public void run() %7B%0A      myQueue.addLast(myRunnable);%0A    %7D%0A%0A    @Override%0A    public int compareTo(Object o) %7B%0A      return myOrder - ((MyUpdate)o).myOrder;%0A    %7D%0A  %7D%0A
 %7D%0A

order fast updates in the queue (EA-34406 - assert: OutputParser.processPacket)