// Copyright (C) 2016 The Android Open Source Project
//
// 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 main

import (
	"flag"
	"path/filepath"
	"strings"

	"android.googlesource.com/platform/tools/gpu/client/gapir"
	"android.googlesource.com/platform/tools/gpu/framework/app"
	"android.googlesource.com/platform/tools/gpu/framework/log"
	"android.googlesource.com/platform/tools/gpu/framework/stringtable"
	"android.googlesource.com/platform/tools/gpu/gapid/auth"
	"android.googlesource.com/platform/tools/gpu/gapid/server"

	_ "android.googlesource.com/platform/tools/gpu/framework/binary/any"
	_ "android.googlesource.com/platform/tools/gpu/internal" // google internal libraries
)

var (
	rpc             = flag.String("rpc", "localhost:0", "TCP host:port of the server's RPC listener")
	logsPath        = flag.String("logs", "logs", "Directory to place log files")
	stringsPath     = flag.String("strings", "strings", "Directory containing string table packages")
	localDevicePort = flag.Int("gapir", 0, "Port number of the \"gapir\" running on the local device, 0 means start new instance")
	persist         = flag.Bool("persist", false, "Server will keep running even when no connections remain")
	gapisAuthToken  = flag.String("gapis-auth-token", "", "The connection authorization token for gapis")
	gapirAuthToken  = flag.String("gapir-auth-token", "", "The connection authorization token for gapir")
	gapirArgStr     = flag.String("gapir-args", "", "\"<The arguments to be passed to gapir>\"")
	useGRpc         = flag.Bool("grpc", false, "Server will bind a grpc service")
)

func main() {
	app.ShortHelp = "Gapis is the graphics API server"
	app.Name = "GAPIS" // Has to be this for version parsing compatability
	app.Version = version
	// We hook into the app intialization phase between parameter parsing and context building
	// This is to allow us to update the logging path using the legacy logs parameter
	// TODO: delete this once there are no instances of a client using the old paths argument
	oldUpdateContext := app.UpdateContext
	app.UpdateContext = func(ctx log.Context, closeLogs log.Closer) (log.Context, log.Closer) {
		if *logsPath != "" && *app.LogFile == "" {
			gapisLogPath, _ := filepath.Abs(filepath.Join(*logsPath, "gapis.log"))
			app.LogFile = &gapisLogPath
		}
		gapir.LogPath, _ = filepath.Abs(filepath.Join(*logsPath, "gapir.log"))
		return oldUpdateContext(ctx, closeLogs)
	}
	app.Run(run)
}

func run(ctx log.Context) error {
	return server.Run(ctx, server.Config{
		RPCAddress:           *rpc,
		ShutdownOnDisconnect: !*persist,
		StringTables:         loadStrings(ctx),
		LocalPort:            *localDevicePort,
		GAPISAuthToken:       auth.Token(*gapisAuthToken),
		GAPIRAuthToken:       auth.Token(*gapirAuthToken),
		GAPIRAdditionalArgs:  strings.Fields(*gapirArgStr),
		UseGRpc:              *useGRpc,
	})
}

func loadStrings(ctx log.Context) []*stringtable.StringTable {
	files, err := filepath.Glob(filepath.Join(*stringsPath, "*.stb"))
	if err != nil {
		ctx.Fail(err, "Couldn't scan for stringtables")
		return nil
	}

	out := make([]*stringtable.StringTable, 0, len(files))

	for _, path := range files {
		ctx := ctx.S("path", path)
		st, err := stringtable.Load(path)
		if err != nil {
			ctx.Fail(err, "Couldn't load stringtable file")
			continue
		}
		out = append(out, st)
	}

	return out
}
