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

import (
	"context"
)

import (
	hessian "github.com/apache/dubbo-go-hessian2"
	"github.com/apache/dubbo-go/common/constant"
	"github.com/apache/dubbo-go/config"
	"github.com/dubbogo/gost/log"
)

func init() {
	config.SetProviderService(new(UserProvider))
	// ------for hessian2------
	hessian.RegisterPOJO(&ContextContent{})
}

type ContextContent struct {
	Path              string
	InterfaceName     string
	DubboVersion      string
	LocalAddr         string
	RemoteAddr        string
	UserDefinedStrVal string
	CtxStrVal         string
	CtxIntVal         int64
}

type UserProvider struct {
}

func (u *UserProvider) GetContext(ctx context.Context, req []interface{}) (*ContextContent, error) {
	gxlog.CInfo("req:%#v", req)
	ctxAtta := ctx.Value(constant.DubboCtxKey("attachment")).(map[string]interface{})
	userDefinedval := ctxAtta["user-defined-value"].(*ContextContent)
	gxlog.CInfo("get user defined struct:%#v", userDefinedval)
	rsp := ContextContent{
		Path:              ctxAtta["path"].(string),
		InterfaceName:     ctxAtta["interface"].(string),
		DubboVersion:      ctxAtta["dubbo"].(string),
		LocalAddr:         ctxAtta["local-addr"].(string),
		RemoteAddr:        ctxAtta["remote-addr"].(string),
		UserDefinedStrVal: userDefinedval.InterfaceName,
		CtxIntVal:         ctxAtta["int-value"].(int64),
		CtxStrVal:         ctxAtta["string-value"].(string),
	}
	gxlog.CInfo("rsp:%#v", rsp)
	return &rsp, nil
}

func (u *UserProvider) Reference() string {
	return "UserProvider"
}

func (u ContextContent) JavaClassName() string {
	return "org.apache.dubbo.ContextContent"
}
