/*
 * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
  @test
  @key headful
  @bug 6392086 8014725
  @summary tests that HTMLs of all supported native HTML formats are transfered
           properly
  @run main/othervm HTMLTransferTest
*/

import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*;

public class HTMLTransferTest {
    public static final int CODE_NOT_RETURNED = 100;
    public static final int CODE_CONSUMER_TEST_FAILED = 101;
    public static final int CODE_FAILURE = 102;
    public static DataFlavor[] HTMLFlavors = null;
    public static DataFlavor SyncFlavor = null;
    static {
        try{
            HTMLFlavors = new DataFlavor[] {
                new DataFlavor("text/html; document=selection; Class=" + InputStream.class.getName() + "; charset=UTF-8"),
                new DataFlavor("text/html; document=selection; Class=" + String.class.getName() + "; charset=UTF-8")
            };
            SyncFlavor = new DataFlavor(
                "application/x-java-serialized-object; class="
                + SyncMessage.class.getName()
                + "; charset=UTF-8"
            );
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    private THTMLProducer imPr;
    private int returnCode = CODE_NOT_RETURNED;

    public static void main(final String[] args) {
        HTMLTransferTest app = new HTMLTransferTest();
        app.init();
        app.start();
    }

    public void init() {
        initImpl();

    } // init()

    private void initImpl() {
        imPr = new THTMLProducer();
        imPr.begin();
    }


    public void start() {
        try {
            String stFormats = "";

            String iniMsg = "Testing formats from the list:\n";
            for (int i = 0; i < HTMLTransferTest.HTMLFlavors.length; i++) {
                stFormats += "\"" + HTMLTransferTest.HTMLFlavors[i].getMimeType() + "\"\n";
            }
            System.out.println(iniMsg + stFormats);
            System.err.println("===>" + iniMsg + stFormats);

            String javaPath = System.getProperty("java.home", "");
            String cmd = javaPath + File.separator + "bin" + File.separator
                + "java -cp " + System.getProperty("test.classes", ".") +
                //+ "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 "
                " THTMLConsumer"
                //+ stFormats
                ;

            Process process = Runtime.getRuntime().exec(cmd);
            ProcessResults pres = ProcessResults.doWaitFor(process);
            returnCode = pres.exitValue;

            if (pres.stderr != null && pres.stderr.length() > 0) {
                System.err.println("========= Child VM System.err ========");
                System.err.print(pres.stderr);
                System.err.println("======================================");
            }

            if (pres.stdout != null && pres.stdout.length() > 0) {
                System.err.println("========= Child VM System.out ========");
                System.err.print(pres.stdout);
                System.err.println("======================================");
            }
        } catch (Throwable e) {
            e.printStackTrace();
            //returnCode equals CODE_NOT_RETURNED
        }

        switch (returnCode) {
        case CODE_NOT_RETURNED:
            System.err.println("Child VM: failed to start");
            break;
        case CODE_FAILURE:
            System.err.println("Child VM: abnormal termination");
            break;
        case CODE_CONSUMER_TEST_FAILED:
            throw new RuntimeException("test failed: HTMLs in some " +
                "native formats are not transferred properly: " +
                "see output of child VM");
        default:
            boolean failed = false;
            String passedFormats = "";
            String failedFormats = "";

            for (int i = 0; i < imPr.passedArray.length; i++) {
               if (imPr.passedArray[i]) {
                   passedFormats += HTMLTransferTest.HTMLFlavors[i].getMimeType() + " ";
               } else {
                   failed = true;
                   failedFormats += HTMLTransferTest.HTMLFlavors[i].getMimeType() + " ";
               }
            }
            if (failed) {
                throw new RuntimeException(
                    "test failed: HTMLs in following "
                    + "native formats are not transferred properly: "
                    + failedFormats
                );
            } else {
                System.err.println(
                    "HTMLs in following native formats are "
                    + "transferred properly: "
                    + passedFormats
                );
            }
        }

    } // start()

} // class HTMLTransferTest

class SyncMessage implements Serializable {
    String msg;

    public SyncMessage(String sync) {
        this.msg = sync;
    }

    @Override
    public boolean equals(Object obj) {
        return this.msg.equals(((SyncMessage)obj).msg);
    }

    @Override
    public String toString() {
        return msg;
    }
}

class ProcessResults {
    public int exitValue;
    public String stdout;
    public String stderr;

    public ProcessResults() {
        exitValue = -1;
        stdout = "";
        stderr = "";
    }

    /**
     * Method to perform a "wait" for a process and return its exit value.
     * This is a workaround for <code>Process.waitFor()</code> never returning.
     */
    public static ProcessResults doWaitFor(Process p) {
        ProcessResults pres = new ProcessResults();

        InputStream in = null;
        InputStream err = null;

        try {
            in = p.getInputStream();
            err = p.getErrorStream();

            boolean finished = false;

            while (!finished) {
                try {
                    while (in.available() > 0) {
                        pres.stdout += (char)in.read();
                    }
                    while (err.available() > 0) {
                        pres.stderr += (char)err.read();
                    }
                    // Ask the process for its exitValue. If the process
                    // is not finished, an IllegalThreadStateException
                    // is thrown. If it is finished, we fall through and
                    // the variable finished is set to true.
                    pres.exitValue = p.exitValue();
                    finished  = true;
                }
                catch (IllegalThreadStateException e) {
                    // Process is not finished yet;
                    // Sleep a little to save on CPU cycles
                    Thread.currentThread().sleep(500);
                }
            }
            if (in != null) in.close();
            if (err != null) err.close();
        }
        catch (Throwable e) {
            System.err.println("doWaitFor(): unexpected exception");
            e.printStackTrace();
        }
        return pres;
    }
}


abstract class HTMLTransferer implements ClipboardOwner {

    static final SyncMessage S_PASSED = new SyncMessage("Y");
    static final SyncMessage S_FAILED = new SyncMessage("N");
    static final SyncMessage S_BEGIN = new SyncMessage("B");
    static final SyncMessage S_BEGIN_ANSWER = new SyncMessage("BA");
    static final SyncMessage S_END = new SyncMessage("E");



    Clipboard m_clipboard;

    HTMLTransferer() {
        m_clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    }


    abstract void notifyTransferSuccess(boolean status);


    static Object createTRInstance(int i) {
        try{
            String _htmlText =
                "The quick <font color='#78650d'>brown</font> <b>mouse</b> jumped over the lazy <b>cat</b>.";
            switch(i){
            case 0:
                return new ByteArrayInputStream(_htmlText.getBytes("utf-8"));
            case 1:
                return _htmlText;
            }
        }catch(UnsupportedEncodingException e){ e.printStackTrace(); }
        return null;
    }

    static byte[] getContent(InputStream is)
    {
        ByteArrayOutputStream tmp = new ByteArrayOutputStream();
        try{
            int read;
            while( -1 != (read = is.read()) ){
                tmp.write(read);
            };
        } catch( IOException e ) {
            e.printStackTrace();
        }
        return tmp.toByteArray();
    }

    static void Dump(byte[] b){
        System.err.println( new String(b) );
    };

    void setClipboardContents(
        Transferable contents,
        ClipboardOwner owner
    ) {
        synchronized (m_clipboard) {
            boolean set = false;
            while (!set) {
                try {
                    m_clipboard.setContents(contents, owner);
                    set = true;
                } catch (IllegalStateException ise) {
                    try {
                        Thread.sleep(100);
                    } catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    Transferable getClipboardContents(Object requestor)
    {
        synchronized (m_clipboard) {
            while (true) {
                try {
                    Transferable t = m_clipboard.getContents(requestor);
                    return t;
                } catch (IllegalStateException ise) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}


class THTMLProducer extends HTMLTransferer {

    boolean[] passedArray;
    int fi = 0; // next format index
    private boolean isFirstCallOfLostOwnership = true;

    THTMLProducer() {
        passedArray = new boolean[HTMLTransferTest.HTMLFlavors.length];
    }

    void begin() {
        setClipboardContents(
            new HTMLSelection(
                HTMLTransferTest.SyncFlavor,
                S_BEGIN
            ),
            this
        );
    }

    public void lostOwnership(Clipboard cb, Transferable contents) {
        System.err.println("{PRODUCER: lost clipboard ownership");
        Transferable t = getClipboardContents(null);
        if (t.isDataFlavorSupported(HTMLTransferTest.SyncFlavor)) {
            SyncMessage msg = null;
            // for test going on if t.getTransferData() will throw an exception
            if (isFirstCallOfLostOwnership) {
                isFirstCallOfLostOwnership = false;
                msg = S_BEGIN_ANSWER;
            } else {
                msg = S_PASSED;
            }
            try {
                msg = (SyncMessage)t.getTransferData(HTMLTransferTest.SyncFlavor);
                System.err.println("++received message: " + msg);
            } catch (Exception e) {
                System.err.println("Can't getTransferData-message: " + e);
            }
            if( msg.equals(S_PASSED) ){
                notifyTransferSuccess(true);
            } else if( msg.equals(S_FAILED) ){
                notifyTransferSuccess(false);
            } else if (!msg.equals(S_BEGIN_ANSWER)) {
                throw new RuntimeException("wrong message in " +
                    "THTMLProducer.lostOwnership(): " + msg +
                    "  (possibly due to bug 4683804)");
            }
        } else {
            throw new RuntimeException(
                "DataFlavor.stringFlavor is not "
                + "suppurted by transferable in "
                + "THTMLProducer.lostOwnership()"
            );
        }

        if (fi < HTMLTransferTest.HTMLFlavors.length) {
            System.err.println(
                "testing native HTML format \""
                + HTMLTransferTest.HTMLFlavors[fi].getMimeType()
                + "\"..."
            );
            //leaveFormat( HTMLTransferTest.HTMLFlavors[fi].getMimeType() );
            setClipboardContents(
                new HTMLSelection(
                    HTMLTransferTest.HTMLFlavors[fi],
                    HTMLTransferer.createTRInstance(fi)
                ),
                this
            );
        } else {
            setClipboardContents(
                new HTMLSelection(
                    HTMLTransferTest.SyncFlavor,
                    S_END
                ),
                null
            );
        }
        System.err.println("}PRODUCER: lost clipboard ownership");
    }


    void notifyTransferSuccess(boolean status) {
        passedArray[fi] = status;
        fi++;
    }

}


class THTMLConsumer extends HTMLTransferer
{
    private static final Object LOCK = new Object();
    private static boolean failed;
    int fi = 0; // next format index

    public void lostOwnership(Clipboard cb, Transferable contents) {
        System.err.println("{CONSUMER: lost clipboard ownership");
        Transferable t = getClipboardContents(null);
        boolean bContinue = true;
        if(t.isDataFlavorSupported(HTMLTransferTest.SyncFlavor)) {
            try {
                SyncMessage msg = (SyncMessage)t.getTransferData(HTMLTransferTest.SyncFlavor);
                System.err.println("received message: " + msg);
                if(msg.equals(S_END)){
                    synchronized (LOCK) {
                        LOCK.notifyAll();
                    }
                    bContinue = false;
                }
            } catch (Exception e) {
                System.err.println("Can't getTransferData-message: " + e);
            }
        }
        if(bContinue){
            // all HTML formats have been processed
            System.err.println( "============================================================");
            System.err.println( "Put as " + HTMLTransferTest.HTMLFlavors[fi].getMimeType() );
            boolean bSuccess = false;
            for(int i = 0; i < HTMLTransferTest.HTMLFlavors.length; ++i) {
                System.err.println( "----------------------------------------------------------");
                if( t.isDataFlavorSupported(HTMLTransferTest.HTMLFlavors[i]) ){
                    Object im = null; //? HTML;
                    try {
                       im = t.getTransferData(HTMLTransferTest.HTMLFlavors[i]);
                       if (im == null) {
                           System.err.println("getTransferData returned null");
                       } else {
                            System.err.println( "Extract as " + HTMLTransferTest.HTMLFlavors[i].getMimeType() );
                            String stIn = "(unknown)", stOut = "(unknown)";
                            switch( i ){
                            case 0:
                                stIn = new String( getContent( (InputStream)HTMLTransferer.createTRInstance(i) ) );
                                stOut = new String( getContent((InputStream)im) );
                                bSuccess = stIn.equals(stOut);
                                break;
                            case 1:
                                stIn = (String)HTMLTransferer.createTRInstance(i);
                                stOut = (String)im;
                                int head = stOut.indexOf("<HTML><BODY>");
                                if (head >= 0) {
                                    stOut = stOut.substring(head + 12, stOut.length() - 14);
                                }
                                bSuccess = stIn.equals(stOut);
                                break;
                            default:
                                bSuccess = HTMLTransferer.createTRInstance(i).equals(im);
                                break;
                            };
                            System.err.println("in :" + stIn);
                            System.err.println("out:" + stOut);
                       };
                    } catch (Exception e) {
                        System.err.println("Can't getTransferData: " + e);
                    }
                    if(!bSuccess)
                        System.err.println("transferred DATA is different from initial DATA\n");
                } else {
                    System.err.println("Flavor is not supported by transferable:\n");
                    DataFlavor[] dfs = t.getTransferDataFlavors();
                    int ii;
                    for(ii = 0; ii < dfs.length; ++ii)
                        System.err.println("Supported:" + dfs[ii] + "\n");
                    dfs = HTMLTransferTest.HTMLFlavors;
                    for(ii = 0; ii < dfs.length; ++ii)
                        System.err.println("Accepted:" + dfs[ii] + "\n" );
                }
            }
            System.err.println( "----------------------------------------------------------");
            notifyTransferSuccess(bSuccess);
            System.err.println( "============================================================");
            ++fi;
        }
        System.err.println("}CONSUMER: lost clipboard ownership");
    }


    void notifyTransferSuccess(boolean status) {
        System.err.println(
            "format "
            + (status
                ? "passed"
                : "failed"
            )
            + "!!!"
        );
        setClipboardContents(
            new HTMLSelection(
                HTMLTransferTest.SyncFlavor,
                status
                    ? S_PASSED
                    : S_FAILED
            ),
            this
        );
    }


    public static void main(String[] args) {
        try {
            System.err.println("{CONSUMER: start");
            THTMLConsumer ic = new THTMLConsumer();
            ic.setClipboardContents(
                new HTMLSelection(
                    HTMLTransferTest.SyncFlavor,
                    S_BEGIN_ANSWER
                ),
                ic
            );
            synchronized (LOCK) {
                LOCK.wait();
            }
            System.err.println("}CONSUMER: start");
        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(HTMLTransferTest.CODE_FAILURE);
        }
    }

}


/**
 * A <code>Transferable</code> which implements the capability required
 * to transfer an <code>HTML</code>.
 *
 * This <code>Transferable</code> properly supports
 * <code>HTMLTransferTest.HTMLFlavors</code>.
 * and all equivalent flavors.
 * No other <code>DataFlavor</code>s are supported.
 *
 * @see java.awt.datatransfer.HTMLTransferTest.HTMLFlavors
 */
class HTMLSelection implements Transferable {
    private DataFlavor m_flavor;
    private Object m_data;

    /**
     * Creates a <code>Transferable</code> capable of transferring
     * the specified <code>String</code>.
     */
    public HTMLSelection(
        DataFlavor flavor,
        Object data
    ){
        m_flavor = flavor;
        m_data = data;
    }

    /**
     * Returns an array of flavors in which this <code>Transferable</code>
     * can provide the data. <code>DataFlavor.stringFlavor</code>
     * is properly supported.
     * Support for <code>DataFlavor.plainTextFlavor</code> is
     * <b>deprecated</b>.
     *
     * @return an array of length one, whose element is <code>DataFlavor.
     *         HTMLTransferTest.HTMLFlavors</code>
     */
    public DataFlavor[] getTransferDataFlavors() {
        // returning flavors itself would allow client code to modify
        // our internal behavior
        return new DataFlavor[]{ m_flavor } ;
    }

    /**
     * Returns whether the requested flavor is supported by this
     * <code>Transferable</code>.
     *
     * @param flavor the requested flavor for the data
     * @return true if <code>flavor</code> is equal to
     *   <code>HTMLTransferTest.HTMLFlavors</code>;
     *   false if <code>flavor</code>
     *   is not one of the above flavors
     * @throws NullPointerException if flavor is <code>null</code>
     */
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        System.err.println("Have:" + flavor + " Can:" + m_flavor);
        if(flavor.equals(m_flavor))
            return true;
        return false;
    }

    /**
     * Returns the <code>Transferable</code>'s data in the requested
     * <code>DataFlavor</code> if possible. If the desired flavor is
     * <code>HTMLTransferTest.HTMLFlavors</code>, or an equivalent flavor,
     * the <code>HTML</code> representing the selection is
     * returned.
     *
     * @param flavor the requested flavor for the data
     * @return the data in the requested flavor, as outlined above
     * @throws UnsupportedFlavorException if the requested data flavor is
     *         not equivalent to <code>HTMLTransferTest.HTMLFlavors</code>
     * @throws IOException if an IOException occurs while retrieving the data.
     *         By default, <code>HTMLSelection</code> never throws
     *         this exception, but a subclass may.
     * @throws NullPointerException if flavor is <code>null</code>
     */
    public Object getTransferData(DataFlavor flavor)
        throws UnsupportedFlavorException, IOException
    {
        if (flavor.equals(m_flavor)) {
            return (Object)m_data;
        } else {
            throw new UnsupportedFlavorException(flavor);
        }
    }

} // class HTMLSelection
