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

import (
	"context"
	"fmt"
	"net/http"
	"net/url"
	"reflect"
	"strings"
	"time"

	"github.com/apache/incubator-devlake/core/models/domainlayer/devops"

	"github.com/apache/incubator-devlake/core/dal"
	"github.com/apache/incubator-devlake/core/errors"
	"github.com/apache/incubator-devlake/core/log"
	"github.com/apache/incubator-devlake/core/plugin"
	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
	githubImpl "github.com/apache/incubator-devlake/plugins/github/impl"
	"github.com/apache/incubator-devlake/plugins/github/models"
	githubTasks "github.com/apache/incubator-devlake/plugins/github/tasks"
	"github.com/apache/incubator-devlake/plugins/github_graphql/model/migrationscripts"
	"github.com/apache/incubator-devlake/plugins/github_graphql/tasks"
	"github.com/merico-dev/graphql"
	"golang.org/x/oauth2"
)

// make sure interface is implemented
var _ interface {
	plugin.PluginMeta
	plugin.PluginTask
	plugin.PluginApi
	plugin.PluginModel
	plugin.PluginSource
	plugin.CloseablePluginTask
	plugin.PluginMigration
} = (*GithubGraphql)(nil)

type GithubGraphql struct{}

func (p GithubGraphql) Connection() dal.Tabler {
	return &models.GithubConnection{}
}

func (p GithubGraphql) Scope() plugin.ToolLayerScope {
	return &models.GithubRepo{}
}

func (p GithubGraphql) ScopeConfig() dal.Tabler {
	return &models.GithubScopeConfig{}
}

func (p GithubGraphql) Description() string {
	return "collect some GithubGraphql data"
}

func (p GithubGraphql) Name() string {
	return "github_graphql"
}

func (p GithubGraphql) GetTablesInfo() []dal.Tabler {
	return []dal.Tabler{
		&models.GithubDeployment{},
	}
}

func (p GithubGraphql) SubTaskMetas() []plugin.SubTaskMeta {
	return []plugin.SubTaskMeta{
		// collect millstones
		githubTasks.CollectMilestonesMeta,
		githubTasks.ExtractMilestonesMeta,

		// collect issue & pr, deps on millstone
		tasks.CollectIssuesMeta,
		tasks.ExtractIssuesMeta,
		tasks.CollectPrsMeta,
		tasks.ExtractPrsMeta,

		// collect workflow run & job
		githubTasks.CollectRunsMeta,
		githubTasks.ExtractRunsMeta,
		tasks.CollectJobsMeta,
		tasks.ExtractJobsMeta,

		// collect others
		githubTasks.CollectApiCommentsMeta,
		githubTasks.ExtractApiCommentsMeta,
		githubTasks.CollectApiEventsMeta,
		githubTasks.ExtractApiEventsMeta,
		githubTasks.CollectApiPrReviewCommentsMeta,
		githubTasks.ExtractApiPrReviewCommentsMeta,

		// collect account, deps on all before
		tasks.CollectAccountMeta,
		tasks.ExtractAccountsMeta,

		// convert to domain layer
		githubTasks.ConvertRunsMeta,
		githubTasks.ConvertJobsMeta,
		githubTasks.EnrichPullRequestIssuesMeta,
		githubTasks.ConvertRepoMeta,
		githubTasks.ConvertIssuesMeta,
		githubTasks.ConvertCommitsMeta,
		githubTasks.ConvertIssueLabelsMeta,
		githubTasks.ConvertPullRequestCommitsMeta,
		githubTasks.ConvertPullRequestsMeta,
		githubTasks.ConvertPullRequestReviewsMeta,
		githubTasks.ConvertPullRequestLabelsMeta,
		githubTasks.ConvertPullRequestIssuesMeta,
		githubTasks.ConvertIssueAssigneeMeta,
		githubTasks.ConvertIssueCommentsMeta,
		githubTasks.ConvertPullRequestCommentsMeta,
		githubTasks.ConvertReviewsMeta,
		githubTasks.ConvertMilestonesMeta,
		githubTasks.ConvertAccountsMeta,

		// deployment
		tasks.CollectDeploymentsMeta,
		tasks.ExtractDeploymentsMeta,
		tasks.ConvertDeploymentsMeta,

		// releases
		tasks.CollectReleaseMeta,
		tasks.ExtractReleasesMeta,
		githubTasks.ConvertReleasesMeta,
	}
}

type GraphQueryRateLimit struct {
	RateLimit struct {
		Limit     graphql.Int
		Remaining graphql.Int
		ResetAt   time.Time
	}
}

func (p GithubGraphql) PrepareTaskData(taskCtx plugin.TaskContext, options map[string]interface{}) (interface{}, errors.Error) {
	logger := taskCtx.GetLogger()
	logger.Debug("%v", options)
	var op githubTasks.GithubOptions
	err := helper.Decode(options, &op, nil)
	if err != nil {
		return nil, err
	}
	connectionHelper := helper.NewConnectionHelper(
		taskCtx,
		nil,
		p.Name(),
	)
	connection := &models.GithubConnection{}
	err = connectionHelper.FirstById(connection, op.ConnectionId)
	if err != nil {
		return nil, errors.Default.Wrap(err, "unable to get github connection by the given connection ID: %v")
	}

	taskData := &githubTasks.GithubTaskData{
		Options: &op,
	}

	syncPolicy := taskCtx.SyncPolicy()
	var enricherApiClient *helper.ApiClient
	if !syncPolicy.SkipCollectors {
		apiClient, err := githubTasks.CreateApiClient(taskCtx, connection)
		if err != nil {
			return nil, errors.Default.Wrap(err, "unable to get github API client instance")
		}
		enricherApiClient = apiClient.ApiClient

		tokens := strings.Split(connection.Token, ",")
		src := oauth2.StaticTokenSource(
			&oauth2.Token{AccessToken: tokens[0]},
		)
		oauthContext := taskCtx.GetContext()
		proxy := connection.GetProxy()
		if proxy != "" {
			pu, err := url.Parse(proxy)
			if err != nil {
				return nil, errors.Convert(err)
			}
			if pu.Scheme == "http" || pu.Scheme == "socks5" {
				proxyClient := &http.Client{
					Transport: &http.Transport{Proxy: http.ProxyURL(pu)},
				}
				oauthContext = context.WithValue(
					taskCtx.GetContext(),
					oauth2.HTTPClient,
					proxyClient,
				)
				logger.Debug("Proxy set in oauthContext to %s", proxy)
			} else {
				return nil, errors.BadInput.New("Unsupported scheme set in proxy")
			}
		}

		httpClient := oauth2.NewClient(oauthContext, src)
		endpoint, err := errors.Convert01(url.Parse(connection.Endpoint))
		if err != nil {
			return nil, errors.BadInput.Wrap(err, fmt.Sprintf("malformed connection endpoint supplied: %s", connection.Endpoint))
		}

		// github.com and github enterprise have different graphql endpoints
		endpoint.Path = "/graphql" // see https://docs.github.com/en/graphql/guides/forming-calls-with-graphql
		if endpoint.Hostname() != "api.github.com" {
			// see https://docs.github.com/en/enterprise-server@3.11/graphql/guides/forming-calls-with-graphql
			endpoint.Path = "/api/graphql"
		}
		client := graphql.NewClient(endpoint.String(), httpClient)
		graphqlClient, err := helper.CreateAsyncGraphqlClient(taskCtx, client, taskCtx.GetLogger(),
			func(ctx context.Context, client *graphql.Client, logger log.Logger) (rateRemaining int, resetAt *time.Time, err errors.Error) {
				var query GraphQueryRateLimit
				dataErrors, err := errors.Convert01(client.Query(taskCtx.GetContext(), &query, nil))
				if err != nil {
					return 0, nil, err
				}
				if len(dataErrors) > 0 {
					return 0, nil, errors.Default.Wrap(dataErrors[0], `query rate limit fail`)
				}
				logger.Info(`github graphql init success with remaining %d/%d and will reset at %s`,
					query.RateLimit.Remaining, query.RateLimit.Limit, query.RateLimit.ResetAt)
				return int(query.RateLimit.Remaining), &query.RateLimit.ResetAt, nil
			})
		if err != nil {
			return nil, err
		}

		graphqlClient.SetGetRateCost(func(q interface{}) int {
			v := reflect.ValueOf(q)
			return int(v.Elem().FieldByName(`RateLimit`).FieldByName(`Cost`).Int())
		})
		taskData.ApiClient = apiClient
		taskData.GraphqlClient = graphqlClient
	}
	err = githubImpl.EnrichOptions(taskCtx, &op, enricherApiClient)
	if err != nil {
		return nil, err
	}

	regexEnricher := helper.NewRegexEnricher()
	if op.ScopeConfig.DeploymentPattern != nil {
		if err = regexEnricher.TryAdd(devops.DEPLOYMENT, *op.ScopeConfig.DeploymentPattern); err != nil {
			return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
		}
	}
	if op.ScopeConfig.ProductionPattern != nil {
		if err = regexEnricher.TryAdd(devops.PRODUCTION, *op.ScopeConfig.ProductionPattern); err != nil {
			return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
		}
	}
	if len(op.ScopeConfig.EnvNameList) > 0 || (len(op.ScopeConfig.EnvNameList) == 0 && op.ScopeConfig.EnvNamePattern == "") {
		if err = regexEnricher.TryAddList(devops.ENV_NAME_PATTERN, op.ScopeConfig.EnvNameList...); err != nil {
			return nil, errors.BadInput.Wrap(err, "invalid value for `envNameList`")
		}
	} else {
		if err = regexEnricher.TryAdd(devops.ENV_NAME_PATTERN, op.ScopeConfig.EnvNamePattern); err != nil {
			return nil, errors.BadInput.Wrap(err, "invalid value for `envNamePattern`")
		}
	}
	taskData.RegexEnricher = regexEnricher

	return taskData, nil
}

// RootPkgPath information lost when compiled as plugin(.so)
func (p GithubGraphql) RootPkgPath() string {
	return "github.com/apache/incubator-devlake/plugins/githubGraphql"
}

func (p GithubGraphql) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
	return nil
}

func (p GithubGraphql) Close(taskCtx plugin.TaskContext) errors.Error {
	data, ok := taskCtx.GetData().(*githubTasks.GithubTaskData)
	if !ok {
		return errors.Default.New(fmt.Sprintf("GetData failed when try to close %+v", taskCtx))
	}
	if data.ApiClient != nil {
		data.ApiClient.Release()
	}
	if data.GraphqlClient != nil {
		data.GraphqlClient.Release()
	}
	return nil
}

func (p GithubGraphql) MigrationScripts() []plugin.MigrationScript {
	return migrationscripts.All()
}
