// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// detect attempts to autodetect the correct
// values of the environment variables
// used by go_ios_exec.
// detect shells out to ideviceinfo, a third party program that can
// be obtained by following the instructions at
// https://github.com/libimobiledevice/libimobiledevice.
package main

import (
	"bytes"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

func main() {
	udids := getLines(exec.Command("idevice_id", "-l"))
	if len(udids) == 0 {
		fail("no udid found; is a device connected?")
	}

	mps := detectMobileProvisionFiles(udids)
	if len(mps) == 0 {
		fail("did not find mobile provision matching device udids %q", udids)
	}

	fmt.Println("# Available provisioning profiles below.")
	fmt.Println("# NOTE: Any existing app on the device with the app id specified by GOIOS_APP_ID")
	fmt.Println("# will be overwritten when running Go programs.")
	for _, mp := range mps {
		fmt.Println()
		f, err := ioutil.TempFile("", "go_ios_detect_")
		check(err)
		fname := f.Name()
		defer os.Remove(fname)

		out := output(parseMobileProvision(mp))
		_, err = f.Write(out)
		check(err)
		check(f.Close())

		cert, err := plistExtract(fname, "DeveloperCertificates:0")
		check(err)
		pcert, err := x509.ParseCertificate(cert)
		check(err)
		fmt.Printf("export GOIOS_DEV_ID=\"%s\"\n", pcert.Subject.CommonName)

		appID, err := plistExtract(fname, "Entitlements:application-identifier")
		check(err)
		fmt.Printf("export GOIOS_APP_ID=%s\n", appID)

		teamID, err := plistExtract(fname, "Entitlements:com.apple.developer.team-identifier")
		check(err)
		fmt.Printf("export GOIOS_TEAM_ID=%s\n", teamID)
	}
}

func detectMobileProvisionFiles(udids [][]byte) []string {
	cmd := exec.Command("mdfind", "-name", ".mobileprovision")
	lines := getLines(cmd)

	var files []string
	for _, line := range lines {
		if len(line) == 0 {
			continue
		}
		xmlLines := getLines(parseMobileProvision(string(line)))
		matches := 0
		for _, udid := range udids {
			for _, xmlLine := range xmlLines {
				if bytes.Contains(xmlLine, udid) {
					matches++
				}
			}
		}
		if matches == len(udids) {
			files = append(files, string(line))
		}
	}
	return files
}

func parseMobileProvision(fname string) *exec.Cmd {
	return exec.Command("security", "cms", "-D", "-i", string(fname))
}

func plistExtract(fname string, path string) ([]byte, error) {
	out, err := exec.Command("/usr/libexec/PlistBuddy", "-c", "Print "+path, fname).CombinedOutput()
	if err != nil {
		return nil, err
	}
	return bytes.TrimSpace(out), nil
}

func getLines(cmd *exec.Cmd) [][]byte {
	out := output(cmd)
	lines := bytes.Split(out, []byte("\n"))
	// Skip the empty line at the end.
	if len(lines[len(lines)-1]) == 0 {
		lines = lines[:len(lines)-1]
	}
	return lines
}

func output(cmd *exec.Cmd) []byte {
	out, err := cmd.Output()
	if err != nil {
		fmt.Println(strings.Join(cmd.Args, "\n"))
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	return out
}

func check(err error) {
	if err != nil {
		fail(err.Error())
	}
}

func fail(msg string, v ...interface{}) {
	fmt.Fprintf(os.Stderr, msg, v...)
	fmt.Fprintln(os.Stderr)
	os.Exit(1)
}
