// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.mojo.bindings;

import android.support.test.filters.SmallTest;

import org.chromium.mojo.MojoTestCase;
import org.chromium.mojo.bindings.BindingsTestUtils.CapturingErrorHandler;
import org.chromium.mojo.bindings.test.mojom.imported.ImportedInterface;
import org.chromium.mojo.bindings.test.mojom.sample.Factory;
import org.chromium.mojo.bindings.test.mojom.sample.NamedObject;
import org.chromium.mojo.bindings.test.mojom.sample.NamedObject.GetNameResponse;
import org.chromium.mojo.bindings.test.mojom.sample.Request;
import org.chromium.mojo.bindings.test.mojom.sample.Response;
import org.chromium.mojo.system.DataPipe.ConsumerHandle;
import org.chromium.mojo.system.MessagePipeHandle;
import org.chromium.mojo.system.Pair;
import org.chromium.mojo.system.impl.CoreImpl;

import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Tests for interfaces / proxies / stubs generated for sample_factory.mojom.
 */
public class InterfacesTest extends MojoTestCase {

    private static final String OBJECT_NAME = "hello world";

    private final List<Closeable> mCloseablesToClose = new ArrayList<Closeable>();

    /**
     * Basic implementation of {@link NamedObject}.
     */
    public static class MockNamedObjectImpl extends CapturingErrorHandler implements NamedObject {

        private String mName = "";

        /**
         * @see org.chromium.mojo.bindings.Interface#close()
         */
        @Override
        public void close() {
        }

        @Override
        public void setName(String name) {
            mName = name;
        }

        @Override
        public void getName(GetNameResponse callback) {
            callback.call(mName);
        }

        public String getNameSynchronously() {
            return mName;
        }
    }

    /**
     * Implementation of {@link GetNameResponse} keeping track of usage.
     */
    public static class RecordingGetNameResponse implements GetNameResponse {
        private String mName;
        private boolean mCalled;

        public RecordingGetNameResponse() {
            reset();
        }

        @Override
        public void call(String name) {
            mName = name;
            mCalled = true;
        }

        public String getName() {
            return mName;
        }

        public boolean wasCalled() {
            return mCalled;
        }

        public void reset() {
            mName = null;
            mCalled = false;
        }
    }

    /**
     * Basic implementation of {@link Factory}.
     */
    public class MockFactoryImpl extends CapturingErrorHandler implements Factory {

        private boolean mClosed = false;

        public boolean isClosed() {
            return mClosed;
        }

        /**
         * @see org.chromium.mojo.bindings.Interface#close()
         */
        @Override
        public void close() {
            mClosed = true;
        }

        @Override
        public void doStuff(Request request, MessagePipeHandle pipe, DoStuffResponse callback) {
            if (pipe != null) {
                pipe.close();
            }
            Response response = new Response();
            response.x = 42;
            callback.call(response, "Hello");
        }

        @Override
        public void doStuff2(ConsumerHandle pipe, DoStuff2Response callback) {
            callback.call("World");
        }

        @Override
        public void createNamedObject(InterfaceRequest<NamedObject> obj) {
            NamedObject.MANAGER.bind(new MockNamedObjectImpl(), obj);
        }

        @Override
        public void requestImportedInterface(InterfaceRequest<ImportedInterface> obj,
                RequestImportedInterfaceResponse callback) {
            throw new UnsupportedOperationException("Not implemented.");
        }

        @Override
        public void takeImportedInterface(ImportedInterface obj,
                TakeImportedInterfaceResponse callback) {
            throw new UnsupportedOperationException("Not implemented.");
        }
    }

    /**
     * Implementation of DoStuffResponse that keeps track of if the response is called.
     */
    public static class DoStuffResponseImpl implements Factory.DoStuffResponse {
        private boolean mResponseCalled = false;

        public boolean wasResponseCalled() {
            return mResponseCalled;
        }

        @Override
        public void call(Response response, String string) {
            mResponseCalled = true;
        }
    }

    /**
     * @see MojoTestCase#tearDown()
     */
    @Override
    protected void tearDown() throws Exception {
        // Close the elements in the reverse order they were added. This is needed because it is an
        // error to close the handle of a proxy without closing the proxy first.
        Collections.reverse(mCloseablesToClose);
        for (Closeable c : mCloseablesToClose) {
            c.close();
        }
        super.tearDown();
    }

    /**
     * Check that the given proxy receives the calls. If |impl| is not null, also check that the
     * calls are forwared to |impl|.
     */
    private void checkProxy(NamedObject.Proxy proxy, MockNamedObjectImpl impl) {
        RecordingGetNameResponse callback = new RecordingGetNameResponse();
        CapturingErrorHandler errorHandler = new CapturingErrorHandler();
        proxy.getProxyHandler().setErrorHandler(errorHandler);

        if (impl != null) {
            assertNull(impl.getLastMojoException());
            assertEquals("", impl.getNameSynchronously());
        }

        proxy.getName(callback);
        runLoopUntilIdle();

        assertNull(errorHandler.getLastMojoException());
        assertTrue(callback.wasCalled());
        assertEquals("", callback.getName());

        callback.reset();
        proxy.setName(OBJECT_NAME);
        runLoopUntilIdle();

        assertNull(errorHandler.getLastMojoException());
        if (impl != null) {
            assertNull(impl.getLastMojoException());
            assertEquals(OBJECT_NAME, impl.getNameSynchronously());
        }

        proxy.getName(callback);
        runLoopUntilIdle();

        assertNull(errorHandler.getLastMojoException());
        assertTrue(callback.wasCalled());
        assertEquals(OBJECT_NAME, callback.getName());
    }

    @SmallTest
    public void testName() {
        assertEquals("sample::NamedObject", NamedObject.MANAGER.getName());
    }

    @SmallTest
    public void testProxyAndStub() {
        MockNamedObjectImpl impl = new MockNamedObjectImpl();
        NamedObject.Proxy proxy =
                NamedObject.MANAGER.buildProxy(null, NamedObject.MANAGER.buildStub(null, impl));

        checkProxy(proxy, impl);
    }

    @SmallTest
    public void testProxyAndStubOverPipe() {
        MockNamedObjectImpl impl = new MockNamedObjectImpl();
        NamedObject.Proxy proxy =
                BindingsTestUtils.newProxyOverPipe(NamedObject.MANAGER, impl, mCloseablesToClose);

        checkProxy(proxy, impl);
    }

    @SmallTest
    public void testFactoryOverPipe() {
        Factory.Proxy proxy = BindingsTestUtils.newProxyOverPipe(
                Factory.MANAGER, new MockFactoryImpl(), mCloseablesToClose);
        Pair<NamedObject.Proxy, InterfaceRequest<NamedObject>> request =
                NamedObject.MANAGER.getInterfaceRequest(CoreImpl.getInstance());
        mCloseablesToClose.add(request.first);
        proxy.createNamedObject(request.second);

        checkProxy(request.first, null);
    }

    @SmallTest
    public void testInterfaceClosing() {
        MockFactoryImpl impl = new MockFactoryImpl();
        Factory.Proxy proxy =
                BindingsTestUtils.newProxyOverPipe(Factory.MANAGER, impl, mCloseablesToClose);

        assertFalse(impl.isClosed());

        proxy.close();
        runLoopUntilIdle();

        assertTrue(impl.isClosed());
    }

    @SmallTest
    public void testResponse() {
        MockFactoryImpl impl = new MockFactoryImpl();
        Factory.Proxy proxy =
                BindingsTestUtils.newProxyOverPipe(Factory.MANAGER, impl, mCloseablesToClose);
        Request request = new Request();
        request.x = 42;
        Pair<MessagePipeHandle, MessagePipeHandle> handles =
                CoreImpl.getInstance().createMessagePipe(null);
        DoStuffResponseImpl response = new DoStuffResponseImpl();
        proxy.doStuff(request, handles.first, response);

        assertFalse(response.wasResponseCalled());

        runLoopUntilIdle();

        assertTrue(response.wasResponseCalled());
    }
}
