/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 project

import (
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"mynewt.apache.org/newt/newt/downloader"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/util"
)

type templateRepo struct {
	owner  string
	name   string
	branch string
}

type PackageWriter struct {
	downloader *downloader.GithubDownloader
	repo       templateRepo
	targetPath string
	template   string
	fullName   string
	project    *Project
}

var TemplateRepoMap = map[string]templateRepo{
	"APP": templateRepo{
		owner:  "runtimeco",
		name:   "mynewt-pkg-app",
		branch: "master",
	},
	"SDK": templateRepo{
		owner:  "apache",
		name:   "mynewt-pkg-sdk",
		branch: "master",
	},
	"BSP": templateRepo{
		owner:  "apache",
		name:   "mynewt-pkg-bsp",
		branch: "master",
	},
	"LIB": templateRepo{
		owner:  "apache",
		name:   "mynewt-pkg-pkg",
		branch: "master",
	},
	"UNITTEST": templateRepo{
		owner:  "runtimeco",
		name:   "mynewt-pkg-unittest",
		branch: "master",
	},

	// Type=pkg is identical to type=lib for backwards compatibility.
	"PKG": templateRepo{
		owner:  "apache",
		name:   "mynewt-pkg-pkg",
		branch: "master",
	},
}

func (pw *PackageWriter) ConfigurePackage(template string, loc string) error {
	tr, ok := TemplateRepoMap[template]
	if !ok {
		return util.NewNewtError(fmt.Sprintf("Cannot find matching "+
			"repository for template %s", template))
	}
	pw.repo = tr

	pw.fullName = path.Clean(loc)
	path := pw.project.Path()
	path = path + "/" + pw.fullName

	if util.NodeExist(path) {
		return util.NewNewtError(fmt.Sprintf("Cannot place a new package in "+
			"%s, path already exists.", path))
	}

	pw.template = template
	pw.targetPath = path

	return nil
}

// Creates a table of search-replace pairs.  These pairs are simple
// substitution rules (i.e., not regexes) that get applied to filenames,
// directory names, and the contents of YAML files.
func (pw *PackageWriter) replacementTable() [][]string {
	pkgBase := path.Base(pw.fullName)

	return [][]string{
		{`$$pkgfullname`, pw.fullName},
		{`$$pkgdir`, path.Dir(pw.fullName)},
		{`$$pkgname`, path.Base(pw.fullName)},

		// Legacy.
		{`your-pkg-name`, `"` + pw.fullName + `"`},
		{`your-path`, pkgBase},
		{`your-source`, pkgBase},
		{`your-file`, pkgBase},
	}
}

// Applies all the substitution rules in the supplied table to a string.
func replaceText(s string, table [][]string) string {
	for _, r := range table {
		s = strings.Replace(s, r[0], r[1], -1)
	}

	return s
}

// Applies all the substitution rules in the supplied table to the contents of
// a file.  If the file contents change as a result, the file gets rewritten.
func fixupFileText(path string, table [][]string) error {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return util.ChildNewtError(err)
	}

	s1 := string(data)
	s2 := replaceText(s1, table)

	if s2 != s1 {
		if err := ioutil.WriteFile(path, []byte(s2), 0666); err != nil {
			return util.ChildNewtError(err)
		}
	}

	return nil
}

// Retrieves the names of all child files and directories.
//
// @param path                  The root directory where the traversal starts.
//
// @return []string             All descendent files.
//         []string             All descendent directories.
//         error                Error
func collectPaths(path string) ([]string, []string, error) {
	files := []string{}
	dirs := []string{}

	collect := func(path string, f os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if f.IsDir() {
			dirs = append(dirs, path)
		} else {
			files = append(files, path)
		}
		return nil
	}
	if err := filepath.Walk(path, collect); err != nil {
		return nil, nil, util.ChildNewtError(err)
	}

	return files, dirs, nil
}

// Customizes a template package.  Renames generic files and directories and
// substitutes text in YAML files.
func (pw *PackageWriter) fixupPkg() error {
	table := pw.replacementTable()
	pkgDir := pw.targetPath

	// Apply the replacement patterns to directory names.
	_, dirs, err := collectPaths(pkgDir)
	if err != nil {
		return err
	}
	for _, d1 := range dirs {
		d2 := replaceText(d1, table)
		if d1 != d2 {
			// Make parent directory to allow multiple replacements in path.
			if err := os.MkdirAll(filepath.Dir(d2), os.ModePerm); err != nil {
				return util.ChildNewtError(err)
			}
			if err := os.Rename(d1, d2); err != nil {
				return util.ChildNewtError(err)
			}
		}
	}

	// Replace text inside YAML files.
	files, _, err := collectPaths(pkgDir)
	if err != nil {
		return err
	}
	for _, f := range files {
		if strings.HasSuffix(f, ".yml") {
			if err := fixupFileText(f, table); err != nil {
				return err
			}
		}
	}

	// Apply the replacement patterns to file names.
	for _, f1 := range files {
		f2 := replaceText(f1, table)
		if f2 != f1 {
			if err := os.Rename(f1, f2); err != nil {
				return util.ChildNewtError(err)
			}
		}
	}

	return nil
}

func (pw *PackageWriter) WritePackage() error {
	dl := pw.downloader

	dl.User = pw.repo.owner
	dl.Repo = pw.repo.name

	util.StatusMessage(util.VERBOSITY_DEFAULT,
		"Download package template for package type %s.\n",
		strings.ToLower(pw.template))

	tmpdir, err := newtutil.MakeTempRepoDir()
	if err != nil {
		return err
	}
	defer os.RemoveAll(tmpdir)

	if err := dl.Clone(pw.repo.branch, tmpdir); err != nil {
		return err
	}

	if err := os.RemoveAll(tmpdir + "/.git/"); err != nil {
		return util.NewNewtError(err.Error())
	}

	if err := util.CopyDir(tmpdir, pw.targetPath); err != nil {
		return err
	}

	if err := pw.fixupPkg(); err != nil {
		return err
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT,
		"Package successfuly installed into %s.\n", pw.targetPath)

	return nil
}

/**
 * Create new PackageWriter structure, and return it
 */
func NewPackageWriter() *PackageWriter {
	proj := GetProject()

	pw := &PackageWriter{
		project:    proj,
		downloader: downloader.NewGithubDownloader(),
	}

	return pw
}
