// Copyright 2015 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 application

import (
	"log"
	"sync"

	"mojo/public/go/bindings"
	"mojo/public/go/system"

	"mojo/public/interfaces/application/application"
	sp "mojo/public/interfaces/application/service_provider"
	"mojo/public/interfaces/application/shell"
)

// Delegate is an interface that your mojo application should implement.
// All methods are called from the same goroutine to make sure that order of
// calls matches the order of messages sent to underlying message pipe.
type Delegate interface {
	// Initialize is called exactly once before any other method.
	Initialize(ctx Context)

	// AcceptConnection is called when another application attempts to open
	// a connection to this application. Close the connection if you no
	// longer need it.
	AcceptConnection(connection *Connection)

	// Quit is called to request the application shut itself down
	// gracefully.
	Quit()
}

// Context is an interface to information about mojo application environment.
type Context interface {
	// URL returns the URL the application was found at, after all mappings,
	// resolution, and redirects.
	URL() string

	// Args returns a list of initial configuration arguments, passed by the
	// Shell.
	Args() []string

	// ConnectToApplication requests a new connection to an application. You
	// should pass a list of services you want to provide to the requested
	// application.
	ConnectToApplication(remoteURL string, providedServices ...ServiceFactory) *OutgoingConnection

	// Close closes the main run loop for this application.
	Close()
}

// ApplicationImpl is an utility class for communicating with the Shell, and
// providing Services to clients.
type ApplicationImpl struct {
	shell *shell.ShellProxy
	args  []string
	url   string
	// Pointer to the stub that runs this instance of ApplicationImpl.
	runner   *bindings.Stub
	quitOnce sync.Once

	delegate Delegate
	// Protects connections, that can be modified concurrently because of
	// ConnectToApplication calls.
	mu          sync.Mutex
	connections []*Connection
}

// Run binds your mojo application to provided message pipe handle and runs it
// until the application is terminated.
func Run(delegate Delegate, applicationRequest system.MojoHandle) {
	messagePipe := system.GetCore().AcquireNativeHandle(applicationRequest).ToMessagePipeHandle()
	appRequest := application.ApplicationRequest{bindings.NewMessagePipeHandleOwner(messagePipe)}
	impl := &ApplicationImpl{
		delegate: delegate,
	}
	stub := application.NewApplicationStub(appRequest, impl, bindings.GetAsyncWaiter())
	impl.runner = stub
	for {
		if err := stub.ServeRequest(); err != nil {
			connectionError, ok := err.(*bindings.ConnectionError)
			if !ok || !connectionError.Closed() {
				log.Println(err)
			}
			impl.RequestQuit()
			break
		}
	}
}

// Mojo application implementation.
func (impl *ApplicationImpl) Initialize(shellPointer shell.ShellPointer, args *[]string, url string) error {
	impl.shell = shell.NewShellProxy(shellPointer, bindings.GetAsyncWaiter())
	if args != nil {
		impl.args = *args
	}
	impl.url = url
	impl.delegate.Initialize(impl)
	return nil
}

// Mojo application implementation.
func (impl *ApplicationImpl) AcceptConnection(requestorURL string, services *sp.ServiceProviderRequest, exposedServices *sp.ServiceProviderPointer, resolvedURL string) error {
	connection := newConnection(requestorURL, services, exposedServices, resolvedURL)
	impl.delegate.AcceptConnection(connection)
	impl.addConnection(connection)
	return nil
}

// Mojo application implementation.
func (impl *ApplicationImpl) RequestQuit() error {
	impl.quitOnce.Do(func() {
		impl.delegate.Quit()
		impl.mu.Lock()
		for _, c := range impl.connections {
			c.Close()
		}
		impl.mu.Unlock()
		impl.shell.Close_proxy()
		impl.runner.Close()
	})
	return nil
}

// Context implementaion.
func (impl *ApplicationImpl) URL() string {
	return impl.url
}

// Context implementaion.
func (impl *ApplicationImpl) Args() []string {
	return impl.args
}

// Context implementaion.
func (impl *ApplicationImpl) ConnectToApplication(remoteURL string, providedServices ...ServiceFactory) *OutgoingConnection {
	servicesRequest, servicesPointer := sp.CreateMessagePipeForServiceProvider()
	exposedServicesRequest, exposedServicesPointer := sp.CreateMessagePipeForServiceProvider()
	if err := impl.shell.ConnectToApplication(remoteURL, &servicesRequest, &exposedServicesPointer); err != nil {
		log.Printf("can't connect to %v: %v", remoteURL, err)
		// In case of error message pipes sent through Shell are closed and
		// the connection will work as if the remote application closed
		// both ServiceProvider's pipes.
	}
	connection := newConnection(impl.url, &exposedServicesRequest, &servicesPointer, remoteURL)
	impl.addConnection(connection)
	return connection.ProvideServices(providedServices...)
}

func (impl *ApplicationImpl) Close() {
	impl.RequestQuit()
}

// addConnection appends connections slice by a provided connection, removing
// connections that have been closed.
func (impl *ApplicationImpl) addConnection(c *Connection) {
	impl.mu.Lock()
	i := 0
	for i < len(impl.connections) {
		if impl.connections[i].isClosed {
			last := len(impl.connections) - 1
			impl.connections[i] = impl.connections[last]
			impl.connections[last] = nil
			impl.connections = impl.connections[:last]
		} else {
			i++
		}
	}
	if !c.isClosed {
		impl.connections = append(impl.connections, c)
	}
	impl.mu.Unlock()
}
