// Copyright 2016 The LUCI Authors.
//
// 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 server

import (
	"context"
	"fmt"
	"html"
	"html/template"
	"net/url"
	"strings"

	"go.chromium.org/luci/appengine/gaeauth/server/internal/authdbimpl"
	"go.chromium.org/luci/gae/service/info"
	"go.chromium.org/luci/server/portal"
)

type settingsPage struct {
	portal.BasePage
}

func (settingsPage) Title(ctx context.Context) (string, error) {
	return "Authorization settings", nil
}

func (settingsPage) Overview(ctx context.Context) (template.HTML, error) {
	serviceAcc, err := info.ServiceAccount(ctx)
	if err != nil {
		return "", err
	}
	return template.HTML(fmt.Sprintf(`<p>LUCI apps should be configured with an
URL to some existing <a href="https://github.com/luci/luci-py/blob/master/appengine/auth_service/README.md">LUCI Auth Service</a>.</p>

<p>This service distributes various authorization related configuration (like
the list of user groups, IP allowlists, OAuth client IDs, etc), which is
required to handle incoming requests. There's usually one instance of this
service per LUCI deployment.</p>

<p>To connect this app to LUCI Auth Service:</p>
<ul>
  <li>
    Figure out what instance of LUCI Auth Service to use. Use a development
    instance of LUCI Auth Service (*-dev) when running code locally or deploying
    to a staging instance.
  </li>
  <li>
    Make sure Google Cloud Pub/Sub API is enabled in the Cloud Console project
    of your app. LUCI Auth Service uses Pub/Sub to propagate changes.
  </li>
  <li>
    Add the service account belonging to your app (<b>%s</b>) to
    <b>auth-trusted-services</b> group on LUCI Auth Service. This authorizes
    your app to receive updates from LUCI Auth Service.
  </li>
  <li>
    Enter the hostname of LUCI Auth Service in the field below and hit
    "Save Settings". It will verify everything is properly configured (or return
    an error message with some clues if not).
  </li>
</ul>`, html.EscapeString(serviceAcc))), nil
}

func (settingsPage) Fields(ctx context.Context) ([]portal.Field, error) {
	return []portal.Field{
		{
			ID:    "AuthServiceURL",
			Title: "Auth service URL",
			Type:  portal.FieldText,
			Validator: func(authServiceURL string) (err error) {
				if authServiceURL != "" {
					_, err = normalizeAuthServiceURL(authServiceURL)
				}
				return err
			},
		},
		{
			ID:    "LatestRev",
			Title: "Latest fetched revision",
			Type:  portal.FieldStatic,
		},
	}, nil
}

func (settingsPage) ReadSettings(ctx context.Context) (map[string]string, error) {
	switch info, err := authdbimpl.GetLatestSnapshotInfo(ctx); {
	case err != nil:
		return nil, err
	case info == nil:
		return map[string]string{
			"AuthServiceURL": "",
			"LatestRev":      "unknown (not configured)",
		}, nil
	default:
		return map[string]string{
			"AuthServiceURL": info.AuthServiceURL,
			"LatestRev":      fmt.Sprintf("%d", info.Rev),
		}, nil
	}
}

func (settingsPage) WriteSettings(ctx context.Context, values map[string]string) error {
	authServiceURL := values["AuthServiceURL"]
	if authServiceURL != "" {
		var err error
		authServiceURL, err = normalizeAuthServiceURL(authServiceURL)
		if err != nil {
			return err
		}
	}
	baseURL := "https://" + info.DefaultVersionHostname(ctx)
	return authdbimpl.ConfigureAuthService(ctx, baseURL, authServiceURL)
}

func normalizeAuthServiceURL(authServiceURL string) (string, error) {
	if !strings.Contains(authServiceURL, "://") {
		authServiceURL = "https://" + authServiceURL
	}
	parsed, err := url.Parse(authServiceURL)
	if err != nil {
		return "", fmt.Errorf("bad URL %q - %s", authServiceURL, err)
	}
	if !parsed.IsAbs() || parsed.Path != "" {
		return "", fmt.Errorf("bad URL %q - must be host root URL", authServiceURL)
	}
	return parsed.String(), nil
}

func init() {
	portal.RegisterPage("auth_service", settingsPage{})
}
