Support sub-commands for the cross-thread trace profiling (#178)

diff --git a/CHANGES.md b/CHANGES.md
index 3b39d1d..2d6cf7d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -38,6 +38,7 @@
 * Adapt the sub-command `metrics` for deprecate scope fron entity by @mrproliu in https://github.com/apache/skywalking-cli/pull/173
 * Add components in topology related sub-commands. @mrproliu in https://github.com/apache/skywalking-cli/pull/175
 * Add the sub-command `metrics nullable` for query the nullable metrics value. @mrproliu in https://github.com/apache/skywalking-cli/pull/176
+* Adapt the sub-command `profiling trace` for adapt the new trace profiling protocol. @mrproliu in https://github.com/apache/skywalking-cli/pull/177
 
 0.10.0
 ------------------
diff --git a/assets/graphqls/profiling/trace/GetProfileAnalyze.graphql b/assets/graphqls/profiling/trace/GetProfileAnalyze.graphql
deleted file mode 100644
index a89d410..0000000
--- a/assets/graphqls/profiling/trace/GetProfileAnalyze.graphql
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to 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. Apache Software Foundation (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.
-
-query ($segmentId: String!, $timeRanges: [ProfileAnalyzeTimeRange!]!) {
-    result: getProfileAnalyze(segmentId: $segmentId, timeRanges: $timeRanges) {
-        trees {
-            elements {
-                id
-                parentId
-                codeSignature
-                duration
-                durationChildExcluded
-                count
-            }
-        }
-    }
-}
diff --git a/assets/graphqls/profiling/trace/GetTaskSegmentList.graphql b/assets/graphqls/profiling/trace/GetSegmentsProfileAnalyze.graphql
similarity index 75%
rename from assets/graphqls/profiling/trace/GetTaskSegmentList.graphql
rename to assets/graphqls/profiling/trace/GetSegmentsProfileAnalyze.graphql
index 9d4e474..b25adb4 100644
--- a/assets/graphqls/profiling/trace/GetTaskSegmentList.graphql
+++ b/assets/graphqls/profiling/trace/GetSegmentsProfileAnalyze.graphql
@@ -15,13 +15,13 @@
 # specific language governing permissions and limitations
 # under the License.
 
-query ($taskId: String!) {
-    result: getProfileTaskSegmentList(taskID: $taskId) {
-        segmentId
-        endpointNames
-        duration
-        start
-        isError
-        traceIds
+query ($queries: [SegmentProfileAnalyzeQuery!]!) {
+    result: getSegmentsProfileAnalyze(queries: $queries) {
+        tip
+        trees {
+            elements {
+                id parentId codeSignature duration durationChildExcluded count
+            }
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/assets/graphqls/profiling/trace/GetTaskSegmentsList.graphql b/assets/graphqls/profiling/trace/GetTaskSegmentsList.graphql
new file mode 100644
index 0000000..a0120e1
--- /dev/null
+++ b/assets/graphqls/profiling/trace/GetTaskSegmentsList.graphql
@@ -0,0 +1,53 @@
+# Licensed to 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. Apache Software Foundation (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.
+
+query ($taskId: ID!) {
+    result: getProfileTaskSegments(taskID: $taskId) {
+        traceId
+        instanceId
+        instanceName
+        endpointNames
+        duration
+        start
+        spans {
+            spanId
+            parentSpanId
+            segmentId
+            refs {
+                traceId parentSegmentId parentSpanId type
+            }
+            serviceCode
+            serviceInstanceName
+            startTime
+            endTime
+            endpointName
+            type
+            peer
+            component
+            isError
+            layer
+            tags {
+                key value
+            }
+            logs {
+                time
+                data { key value }
+            }
+            profiled
+        }
+    }
+}
\ No newline at end of file
diff --git a/internal/commands/profiling/trace/getProfileAnalyze.go b/internal/commands/profiling/trace/getProfileAnalyze.go
index cff937a..676e59e 100644
--- a/internal/commands/profiling/trace/getProfileAnalyze.go
+++ b/internal/commands/profiling/trace/getProfileAnalyze.go
@@ -37,8 +37,8 @@
 	ArgsUsage: "[parameters...]",
 	Flags: []cli.Flag{
 		&cli.StringFlag{
-			Name:  "segment-id",
-			Usage: "profiled segment id.",
+			Name:  "segment-ids",
+			Usage: "profiled segment ids, multiple id split by ',': s1,s2",
 		},
 		&cli.StringFlag{
 			Name:  "time-ranges",
@@ -46,10 +46,11 @@
 		},
 	},
 	Action: func(ctx *cli.Context) error {
-		segmentID := ctx.String("segment-id")
+		segmentIDs := ctx.String("segment-ids")
+		segmentIDList := strings.Split(segmentIDs, ",")
 
 		tagStr := ctx.String("time-ranges")
-		var timeRanges []*api.ProfileAnalyzeTimeRange = nil
+		var queries []*api.SegmentProfileAnalyzeQuery = nil
 		if tagStr != "" {
 			tagArr := strings.Split(tagStr, ",")
 			for _, tag := range tagArr {
@@ -62,16 +63,25 @@
 				if err != nil {
 					return err
 				}
-				timeRanges = append(timeRanges, &api.ProfileAnalyzeTimeRange{Start: start, End: end})
+
+				// adding time range to each segments
+				for _, segmentID := range segmentIDList {
+					queries = append(queries, &api.SegmentProfileAnalyzeQuery{
+						SegmentID: segmentID,
+						TimeRange: &api.ProfileAnalyzeTimeRange{
+							Start: start, End: end,
+						},
+					})
+				}
 			}
 		}
 
-		analysis, err := profiling.GetTraceProfilingAnalyze(ctx, segmentID, timeRanges)
+		analysis, err := profiling.GetTraceProfilingAnalyze(ctx, queries)
 
 		if err != nil {
 			return err
 		}
 
-		return display.Display(ctx, &displayable.Displayable{Data: analysis, Condition: segmentID})
+		return display.Display(ctx, &displayable.Displayable{Data: analysis, Condition: segmentIDs})
 	},
 }
diff --git a/internal/commands/profiling/trace/getProfiledSegment.go b/internal/commands/profiling/trace/getProfiledSegment.go
deleted file mode 100644
index b6a363a..0000000
--- a/internal/commands/profiling/trace/getProfiledSegment.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to 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. Apache Software Foundation (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 trace
-
-import (
-	"github.com/apache/skywalking-cli/pkg/display"
-	"github.com/apache/skywalking-cli/pkg/display/displayable"
-	"github.com/apache/skywalking-cli/pkg/graphql/profiling"
-
-	"github.com/urfave/cli/v2"
-)
-
-var getProfiledSegmentCommand = &cli.Command{
-	Name:    "profiled-segment",
-	Aliases: []string{"ps"},
-	Usage:   "Analyze profiled segment with time ranges",
-	UsageText: `Analyze profiled segment with time ranges.
-
-Examples:
-1. Analyze profiled segment with time ranges.
-$ swctl profiling trace profiled-segment --segment-id=<segment-id>`,
-	Flags: []cli.Flag{
-		&cli.StringFlag{
-			Name:  "segment-id",
-			Usage: "profiled segment id.",
-		},
-	},
-	Action: func(ctx *cli.Context) error {
-		segmentID := ctx.String("segment-id")
-		segment, err := profiling.GetTraceProfilingSegment(ctx, segmentID)
-
-		if err != nil {
-			return err
-		}
-
-		return display.Display(ctx, &displayable.Displayable{Data: segment, Condition: segmentID})
-	},
-}
diff --git a/internal/commands/profiling/trace/getTaskSegmentList.go b/internal/commands/profiling/trace/getTaskSegmentList.go
index b0ce7e1..58b78dd 100644
--- a/internal/commands/profiling/trace/getTaskSegmentList.go
+++ b/internal/commands/profiling/trace/getTaskSegmentList.go
@@ -28,11 +28,11 @@
 var getTaskSegmentListCommand = &cli.Command{
 	Name:    "segment-list",
 	Aliases: []string{"sl"},
-	Usage:   "Query profiling trace task segment list",
-	UsageText: `Query profiling trace task segment list
+	Usage:   "Query profiling trace task segments list",
+	UsageText: `Query profiling trace task segments list
 
 Examples:
-1. Query profiled segment list
+1. Query profiled segments list
 $ swctl profiling trace segment-list --service-name=service-name --endpoint-name=endpoint`,
 	Flags: []cli.Flag{
 		&cli.StringFlag{
diff --git a/internal/commands/profiling/trace/trace.go b/internal/commands/profiling/trace/trace.go
index e26b308..5c0df87 100644
--- a/internal/commands/profiling/trace/trace.go
+++ b/internal/commands/profiling/trace/trace.go
@@ -33,7 +33,6 @@
 		getTaskListCommand,
 		getTaskLogListCommand,
 		getTaskSegmentListCommand,
-		getProfiledSegmentCommand,
 		getProfiledAnalyzeCommand,
 	},
 }
diff --git a/pkg/graphql/profiling/trace.go b/pkg/graphql/profiling/trace.go
index 6e78ce5..a1e0b47 100644
--- a/pkg/graphql/profiling/trace.go
+++ b/pkg/graphql/profiling/trace.go
@@ -62,10 +62,10 @@
 	return response["result"], err
 }
 
-func GetTraceProfilingTaskSegmentList(ctx *cli.Context, taskID string) ([]*api.BasicTrace, error) {
-	var response map[string][]*api.BasicTrace
+func GetTraceProfilingTaskSegmentList(ctx *cli.Context, taskID string) ([]*api.ProfiledTraceSegments, error) {
+	var response map[string][]*api.ProfiledTraceSegments
 
-	request := graphql.NewRequest(assets.Read("graphqls/profiling/trace/GetTaskSegmentList.graphql"))
+	request := graphql.NewRequest(assets.Read("graphqls/profiling/trace/GetTaskSegmentsList.graphql"))
 	request.Var("taskId", taskID)
 
 	err := client.ExecuteQuery(ctx, request, &response)
@@ -73,23 +73,11 @@
 	return response["result"], err
 }
 
-func GetTraceProfilingSegment(ctx *cli.Context, segmentID string) (api.ProfiledSegment, error) {
-	var response map[string]api.ProfiledSegment
-
-	request := graphql.NewRequest(assets.Read("graphqls/profiling/trace/GetProfiledSegment.graphql"))
-	request.Var("segmentId", segmentID)
-
-	err := client.ExecuteQuery(ctx, request, &response)
-
-	return response["result"], err
-}
-
-func GetTraceProfilingAnalyze(ctx *cli.Context, segmentID string, timeRanges []*api.ProfileAnalyzeTimeRange) (api.ProfileAnalyzation, error) {
+func GetTraceProfilingAnalyze(ctx *cli.Context, queries []*api.SegmentProfileAnalyzeQuery) (api.ProfileAnalyzation, error) {
 	var response map[string]api.ProfileAnalyzation
 
-	request := graphql.NewRequest(assets.Read("graphqls/profiling/trace/GetProfileAnalyze.graphql"))
-	request.Var("segmentId", segmentID)
-	request.Var("timeRanges", timeRanges)
+	request := graphql.NewRequest(assets.Read("graphqls/profiling/trace/GetSegmentsProfileAnalyze.graphql"))
+	request.Var("queries", queries)
 
 	err := client.ExecuteQuery(ctx, request, &response)