/*
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 cmd

import (
	"context"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path"
	"strings"

	"github.com/apache/camel-k/pkg/util"

	"golang.org/x/oauth2"

	"github.com/google/go-github/v32/github"
	"github.com/pkg/errors"
)

// Source ---
type Source struct {
	Origin   string
	Location string
	Name     string
	Content  string
	Compress bool
	Local    bool
}

func (s *Source) setContent(content []byte) error {
	if s.Compress {
		result, err := compressToString(content)
		if err != nil {
			return err
		}

		s.Content = result
	} else {
		s.Content = string(content)
	}

	return nil
}

// ResolveSources ---
func ResolveSources(ctx context.Context, locations []string, compress bool) ([]Source, error) {
	sources := make([]Source, 0, len(locations))

	for _, location := range locations {
		if isLocal(location) {
			answer, err := ResolveLocalSource(location, compress)
			if err != nil {
				return sources, err
			}

			sources = append(sources, answer)
		} else {
			u, err := url.Parse(location)
			if err != nil {
				return sources, err
			}

			switch {
			case u.Scheme == "gist" || strings.HasPrefix(location, "https://gist.github.com/"):
				var tc *http.Client

				if token, ok := os.LookupEnv("GITHUB_TOKEN"); ok {
					ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
					tc = oauth2.NewClient(ctx, ts)

					fmt.Println("GITHUB_TOKEN env var detected, using it for GitHub APIs authentication")
				}

				gc := github.NewClient(tc)
				gistID := ""

				if strings.HasPrefix(location, "https://gist.github.com/") {
					names := util.FindNamedMatches(`^https://gist.github.com/(([a-zA-Z0-9]*)/)?(?P<gistid>[a-zA-Z0-9]*)$`, location)
					if value, ok := names["gistid"]; ok {
						gistID = value
					}
				} else {
					gistID = u.Opaque
				}

				if gistID == "" {
					return sources, fmt.Errorf("unable to determing gist id from %s", location)
				}

				gists, _, err := gc.Gists.Get(ctx, gistID)
				if err != nil {
					return sources, err
				}

				for _, v := range gists.Files {
					if v.Filename == nil || v.Content == nil {
						continue
					}

					answer := Source{
						Name:     *v.Filename,
						Compress: compress,
						Origin:   location,
					}
					if v.RawURL != nil {
						answer.Location = *v.RawURL
					}
					if err := answer.setContent([]byte(*v.Content)); err != nil {
						return sources, err
					}
					sources = append(sources, answer)
				}
			case u.Scheme == "github":
				answer := Source{
					Name:     path.Base(location),
					Origin:   location,
					Location: location,
					Compress: compress,
				}

				content, err := loadContentGitHub(u)
				if err != nil {
					return sources, err
				}
				if err := answer.setContent(content); err != nil {
					return sources, err
				}
				sources = append(sources, answer)
			case u.Scheme == "http":
				answer := Source{
					Name:     path.Base(location),
					Origin:   location,
					Location: location,
					Compress: compress,
				}

				content, err := loadContentHTTP(u)
				if err != nil {
					return sources, err
				}
				if err := answer.setContent(content); err != nil {
					return sources, err
				}
				sources = append(sources, answer)
			case u.Scheme == "https":
				answer := Source{
					Name:     path.Base(location),
					Origin:   location,
					Location: location,
					Compress: compress,
				}

				content, err := loadContentHTTP(u)
				if err != nil {
					return sources, err
				}
				if err := answer.setContent(content); err != nil {
					return sources, err
				}
				sources = append(sources, answer)
			}
		}
	}

	return sources, nil
}

// ResolveLocalSource --
func ResolveLocalSource(location string, compress bool) (Source, error) {
	if _, err := os.Stat(location); err != nil && os.IsNotExist(err) {
		return Source{}, errors.Wrapf(err, "file %s does not exist", location)
	} else if err != nil {
		return Source{}, errors.Wrapf(err, "error while accessing file %s", location)
	}

	answer := Source{
		Name:     path.Base(location),
		Origin:   location,
		Location: location,
		Compress: compress,
		Local:    true,
	}

	content, err := ioutil.ReadFile(location)
	if err != nil {
		return Source{}, err
	}
	if err := answer.setContent(content); err != nil {
		return Source{}, err
	}

	return answer, nil
}
