// 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 main

import (
	"fmt"
	"os"
	"path/filepath"

	"v.io/jiri"
)

func runBuildFramework(jirix *jiri.X) error {
	if flagTargetArch != targetArchAll {
		// The target itself requires cgo binaries of each architecture and thus xcode
		// will fail otherwise.
		return fmt.Errorf("Framework builds are always universal -- target must be all")
	}
	xcodeTarget := selectedProject.frameworkBinaryName
	sh.Pushd(filepath.Join(jirix.Root, "release/swift", selectedProject.directoryName))
	// Make sure target directory exists
	sh.Cmd("mkdir", "-p", flagOutDirSwift).Run()
	// Clear out the old framework
	sanityCheckDir(flagOutDirSwift)
	targetPath := filepath.Join(flagOutDirSwift, selectedProject.frameworkName)
	verbose(jirix, "Building framework at %v\n", targetPath)
	if pathExists(targetPath) {
		verbose(jirix, "Removing old framework at %v\n", targetPath)
		if err := os.RemoveAll(targetPath); err != nil {
			return err
		}
	}
	return buildUniversalFramework(jirix, xcodeTarget)
}

func buildUniversalFramework(jirix *jiri.X, xcodeTarget string) error {
	fatBinaryPath := filepath.Join(flagOutDirSwift, selectedProject.frameworkName, selectedProject.frameworkBinaryName)
	didCopyFramework := false
	for _, targetArch := range targetArchs {
		buildDir, err := buildSingleFramework(jirix, xcodeTarget, targetArch)
		if err != nil {
			return err
		}
		builtFrameworkPath := filepath.Join(buildDir, selectedProject.frameworkName)
		if !didCopyFramework {
			verbose(jirix, "Copying framework from %v to %v\n", builtFrameworkPath, flagOutDirSwift)
			sh.Cmd("cp", "-r", builtFrameworkPath, flagOutDirSwift).Run()
			didCopyFramework = true
			continue
		}
		// Copy this architecture's swift modules
		builtModulesPath := filepath.Join(builtFrameworkPath, "Modules", selectedProject.frameworkBinaryName+".swiftmodule")
		targetModulesPath := filepath.Join(flagOutDirSwift, selectedProject.frameworkName, "Modules", selectedProject.frameworkBinaryName+".swiftmodule")
		verbose(jirix, "Copying built modules from %v to %v\n", filepath.Join(builtModulesPath, "*"), targetModulesPath)
		modules, err := filepath.Glob(filepath.Join(builtModulesPath, "*"))
		if err != nil {
			return err
		}
		for _, module := range modules {
			sh.Cmd("cp", "-f", module, targetModulesPath).Run()
		}
		// Inject the architecture binary
		sh.Cmd("lipo", fatBinaryPath, filepath.Join(builtFrameworkPath, selectedProject.frameworkBinaryName), "-create", "-output", fatBinaryPath).Run()
	}
	return nil
}

func buildSingleFramework(jirix *jiri.X, xcodeTarget string, targetArch string) (string, error) {
	buildDir := sh.MakeTempDir()
	appleArch, err := appleArchFromGoArch(targetArch)
	if err != nil {
		return "", err
	}
	configuration := "Release"
	if !flagReleaseMode {
		configuration = "Debug"
	}
	sdk := "iphoneos"
	if targetArch == targetArchAmd64 {
		sdk = "iphonesimulator"
	}
	if err := os.RemoveAll("build"); err != nil {
		return "", nil
	}
	verbose(jirix, "Building target %v for architecture %v in %v configuration\n", xcodeTarget, appleArch, configuration)
	cmd := sh.Cmd("xcodebuild", "-target", xcodeTarget, "-arch", appleArch, "-configuration", configuration, "-sdk", sdk, "CONFIGURATION_BUILD_DIR="+buildDir, "VALID_ARCHS="+appleArch)
	cmd.PropagateOutput = true
	cmd.Run()
	if err := os.RemoveAll("build"); err != nil {
		return "", nil
	}
	return buildDir, nil
}
