// Copyright 2015 The Vanadium 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 dart_profile implements the dart profile.
package dart_profile

import (
	"flag"
	"fmt"
	"path/filepath"

	"v.io/jiri"
	"v.io/jiri/profiles"
	"v.io/jiri/profiles/profilesmanager"
	"v.io/jiri/profiles/profilesutil"
	"v.io/x/lib/envvar"
)

type versionSpec struct {
	// Version of Dart SDK to install.
	// See https://www.dartlang.org/downloads/archive/ and
	// https://www.dartlang.org/downloads/archive/#direct-download-urls
	dartSdkVersion string

	// Channel for the Dart SDK.  Must be "stable" or "dev".
	dartSdkChannel string
}

func Register(installer, profile string) {
	m := &Manager{
		profileInstaller: installer,
		profileName:      profile,
		qualifiedName:    profiles.QualifiedProfileName(installer, profile),
		versionInfo: profiles.NewVersionInfo(profile, map[string]interface{}{
			"1.14.0-dev.1.0": &versionSpec{
				dartSdkChannel: "dev",
				dartSdkVersion: "1.14.0-dev.1.0",
			},
		}, "1.14.0-dev.1.0"),
	}
	profilesmanager.Register(m)
}

type Manager struct {
	profileInstaller, profileName, qualifiedName string
	root, dartRoot, dartInstDir                  jiri.RelPath
	versionInfo                                  *profiles.VersionInfo
	spec                                         versionSpec
}

func (m Manager) Name() string {
	return m.profileName
}

func (m Manager) Installer() string {
	return m.profileInstaller
}
func (m Manager) String() string {
	return fmt.Sprintf("%s[%s]", m.qualifiedName, m.versionInfo.Default())
}

func (m Manager) VersionInfo() *profiles.VersionInfo {
	return m.versionInfo
}

func (m Manager) Info() string {
	return `Installs the Dart SDK.`
}

func (m *Manager) AddFlags(flags *flag.FlagSet, action profiles.Action) {
}

func (m *Manager) initForTarget(jirix *jiri.X, root jiri.RelPath, target *profiles.Target) error {
	if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
		return err
	}
	m.dartRoot = root.Join("dart")
	m.dartInstDir = m.dartRoot.Join(target.OS(), m.spec.dartSdkChannel, m.spec.dartSdkVersion)
	return nil
}

func (m *Manager) OSPackages(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) ([]string, error) {
	return nil, nil
}

func (m *Manager) Install(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
	if err := m.initForTarget(jirix, root, &target); err != nil {
		return err
	}

	if err := m.installDartSdk(jirix, target, m.dartInstDir.Abs(jirix)); err != nil {
		return err
	}

	target.Env.Vars = envvar.MergeSlices(target.Env.Vars, []string{
		"DART_SDK=" + m.dartInstDir.Symbolic(),
		"PATH=" + m.dartInstDir.Join("bin").Symbolic(),
	})

	target.InstallationDir = string(m.dartInstDir)
	pdb.InstallProfile(m.profileInstaller, m.profileName, string(m.dartRoot))
	return pdb.AddProfileTarget(m.profileInstaller, m.profileName, target)
}

func (m *Manager) installDartSdk(jirix *jiri.X, target profiles.Target, outDir string) error {
	tmpDir, err := jirix.NewSeq().TempDir("", "")
	if err != nil {
		return err
	}
	defer jirix.NewSeq().RemoveAll(tmpDir)

	fn := func() error {
		sdkUrl := dartSdkUrl(m.spec.dartSdkChannel, m.spec.dartSdkVersion, target.OS())
		sdkZipFile := filepath.Join(tmpDir, "dart-sdk.zip")
		return jirix.NewSeq().
			Call(func() error {
				return profilesutil.Fetch(jirix, sdkZipFile, sdkUrl)
			}, "fetch dart sdk").
			Call(func() error { return profilesutil.Unzip(jirix, sdkZipFile, tmpDir) }, "unzip dart sdk").
			MkdirAll(filepath.Dir(outDir), profilesutil.DefaultDirPerm).
			Rename(filepath.Join(tmpDir, "dart-sdk"), outDir).
			Done()
	}
	return profilesutil.AtomicAction(jirix, fn, outDir, "Install Dart SDK")
}

func (m *Manager) Uninstall(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
	if err := m.initForTarget(jirix, root, &target); err != nil {
		return err
	}
	if err := jirix.NewSeq().RemoveAll(m.dartInstDir.Abs(jirix)).Done(); err != nil {
		return err
	}
	pdb.RemoveProfileTarget(m.profileInstaller, m.profileName, target)
	return nil
}

// dartSdkUrl returns the url for the dart SDK with the given version and OS.
func dartSdkUrl(channel, version, os string) string {
	if os == "darwin" {
		os = "macos"
	}
	return fmt.Sprintf("https://storage.googleapis.com/dart-archive/channels/%s/release/%s/sdk/dartsdk-%s-x64-release.zip", channel, version, os)
}
