{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-}

-- Derived from AWS service descriptions, licensed under Apache 2.0.

-- |
-- Module      : Amazonka.ResourceGroups.Types.ResourceQuery
-- Copyright   : (c) 2013-2023 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay
-- Stability   : auto-generated
-- Portability : non-portable (GHC extensions)
module Amazonka.ResourceGroups.Types.ResourceQuery where

import qualified Amazonka.Core as Core
import qualified Amazonka.Core.Lens.Internal as Lens
import qualified Amazonka.Data as Data
import qualified Amazonka.Prelude as Prelude
import Amazonka.ResourceGroups.Types.QueryType

-- | The query that is used to define a resource group or a search for
-- resources. A query specifies both a query type and a query string as a
-- JSON object. See the examples section for example JSON strings.
--
-- The examples that follow are shown as standard JSON strings. If you
-- include such a string as a parameter to the AWS CLI or an SDK API, you
-- might need to \'escape\' the string into a single line. For example, see
-- the
-- <https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html Quoting strings>
-- in the /AWS CLI User Guide/.
--
-- __Example 1__
--
-- The following generic example shows a resource query JSON string that
-- includes only resources that meet the following criteria:
--
-- -   The resource type must be either @resource_type1@ or
--     @resource_type2@.
--
-- -   The resource must have a tag @Key1@ with a value of either @ValueA@
--     or @ValueB@.
--
-- -   The resource must have a tag @Key2@ with a value of either @ValueC@
--     or @ValueD@.
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": { \"ResourceTypeFilters\": [ \"resource_type1\", \"resource_type2\"], \"TagFilters\": [ { \"Key\": \"Key1\", \"Values\": [\"ValueA\",\"ValueB\"] }, { \"Key\":\"Key2\", \"Values\":[\"ValueC\",\"ValueD\"] } ] } }@
--
-- This has the equivalent \"shortcut\" syntax of the following:
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": { \"ResourceTypeFilters\": [ \"resource_type1\", \"resource_type2\"], \"TagFilters\": [ { \"Key1\": [\"ValueA\",\"ValueB\"] }, { \"Key2\": [\"ValueC\",\"ValueD\"] } ] } }@
--
-- __Example 2__
--
-- The following example shows a resource query JSON string that includes
-- only Amazon EC2 instances that are tagged @Stage@ with a value of
-- @Test@.
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": \"{ \"ResourceTypeFilters\": \"AWS::EC2::Instance\", \"TagFilters\": { \"Stage\": \"Test\" } } }@
--
-- __Example 3__
--
-- The following example shows a resource query JSON string that includes
-- resource of any supported type as long as it is tagged @Stage@ with a
-- value of @Prod@.
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": { \"ResourceTypeFilters\": \"AWS::AllSupported\", \"TagFilters\": { \"Stage\": \"Prod\" } } }@
--
-- __Example 4__
--
-- The following example shows a resource query JSON string that includes
-- only Amazon EC2 instances and Amazon S3 buckets that are part of the
-- specified AWS CloudFormation stack.
--
-- @{ \"Type\": \"CLOUDFORMATION_STACK_1_0\", \"Query\": { \"ResourceTypeFilters\": [ \"AWS::EC2::Instance\", \"AWS::S3::Bucket\" ], \"StackIdentifier\": \"arn:aws:cloudformation:us-west-2:123456789012:stack\/AWStestuseraccount\/fb0d5000-aba8-00e8-aa9e-50d5cEXAMPLE\" } }@
--
-- /See:/ 'newResourceQuery' smart constructor.
data ResourceQuery = ResourceQuery'
  { -- | The type of the query. You can use the following values:
    --
    -- -   /@CLOUDFORMATION_STACK_1_0:@/ Specifies that the @Query@ contains an
    --     ARN for a CloudFormation stack.
    --
    -- -   /@TAG_FILTERS_1_0:@/ Specifies that the @Query@ parameter contains a
    --     JSON string that represents a collection of simple tag filters for
    --     resource types and tags. The JSON string uses a syntax similar to
    --     the
    --     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html GetResources>@ @
    --     operation, but uses only the
    --     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html#resourcegrouptagging-GetResources-request-ResourceTypeFilters ResourceTypeFilters>@ @
    --     and
    --     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html#resourcegrouptagging-GetResources-request-TagFiltersTagFilters TagFilters>@ @
    --     fields. If you specify more than one tag key, only resources that
    --     match all tag keys, and at least one value of each specified tag
    --     key, are returned in your query. If you specify more than one value
    --     for a tag key, a resource matches the filter if it has a tag key
    --     value that matches /any/ of the specified values.
    --
    --     For example, consider the following sample query for resources that
    --     have two tags, @Stage@ and @Version@, with two values each:
    --
    --     @[{\"Stage\":[\"Test\",\"Deploy\"]},{\"Version\":[\"1\",\"2\"]}]@
    --
    --     The results of this query could include the following.
    --
    --     -   An EC2 instance that has the following two tags:
    --         @{\"Stage\":\"Deploy\"}@, and @{\"Version\":\"2\"}@
    --
    --     -   An S3 bucket that has the following two tags:
    --         @{\"Stage\":\"Test\"}@, and @{\"Version\":\"1\"}@
    --
    --     The query would not include the following items in the results,
    --     however.
    --
    --     -   An EC2 instance that has only the following tag:
    --         @{\"Stage\":\"Deploy\"}@.
    --
    --         The instance does not have __all__ of the tag keys specified in
    --         the filter, so it is excluded from the results.
    --
    --     -   An RDS database that has the following two tags:
    --         @{\"Stage\":\"Archived\"}@ and @{\"Version\":\"4\"}@
    --
    --         The database has all of the tag keys, but none of those keys has
    --         an associated value that matches at least one of the specified
    --         values in the filter.
    ResourceQuery -> QueryType
type' :: QueryType,
    -- | The query that defines a group or a search.
    ResourceQuery -> Text
query :: Prelude.Text
  }
  deriving (ResourceQuery -> ResourceQuery -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResourceQuery -> ResourceQuery -> Bool
$c/= :: ResourceQuery -> ResourceQuery -> Bool
== :: ResourceQuery -> ResourceQuery -> Bool
$c== :: ResourceQuery -> ResourceQuery -> Bool
Prelude.Eq, ReadPrec [ResourceQuery]
ReadPrec ResourceQuery
Int -> ReadS ResourceQuery
ReadS [ResourceQuery]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ResourceQuery]
$creadListPrec :: ReadPrec [ResourceQuery]
readPrec :: ReadPrec ResourceQuery
$creadPrec :: ReadPrec ResourceQuery
readList :: ReadS [ResourceQuery]
$creadList :: ReadS [ResourceQuery]
readsPrec :: Int -> ReadS ResourceQuery
$creadsPrec :: Int -> ReadS ResourceQuery
Prelude.Read, Int -> ResourceQuery -> ShowS
[ResourceQuery] -> ShowS
ResourceQuery -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResourceQuery] -> ShowS
$cshowList :: [ResourceQuery] -> ShowS
show :: ResourceQuery -> String
$cshow :: ResourceQuery -> String
showsPrec :: Int -> ResourceQuery -> ShowS
$cshowsPrec :: Int -> ResourceQuery -> ShowS
Prelude.Show, forall x. Rep ResourceQuery x -> ResourceQuery
forall x. ResourceQuery -> Rep ResourceQuery x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ResourceQuery x -> ResourceQuery
$cfrom :: forall x. ResourceQuery -> Rep ResourceQuery x
Prelude.Generic)

-- |
-- Create a value of 'ResourceQuery' with all optional fields omitted.
--
-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
--
-- The following record fields are available, with the corresponding lenses provided
-- for backwards compatibility:
--
-- 'type'', 'resourceQuery_type' - The type of the query. You can use the following values:
--
-- -   /@CLOUDFORMATION_STACK_1_0:@/ Specifies that the @Query@ contains an
--     ARN for a CloudFormation stack.
--
-- -   /@TAG_FILTERS_1_0:@/ Specifies that the @Query@ parameter contains a
--     JSON string that represents a collection of simple tag filters for
--     resource types and tags. The JSON string uses a syntax similar to
--     the
--     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html GetResources>@ @
--     operation, but uses only the
--     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html#resourcegrouptagging-GetResources-request-ResourceTypeFilters ResourceTypeFilters>@ @
--     and
--     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html#resourcegrouptagging-GetResources-request-TagFiltersTagFilters TagFilters>@ @
--     fields. If you specify more than one tag key, only resources that
--     match all tag keys, and at least one value of each specified tag
--     key, are returned in your query. If you specify more than one value
--     for a tag key, a resource matches the filter if it has a tag key
--     value that matches /any/ of the specified values.
--
--     For example, consider the following sample query for resources that
--     have two tags, @Stage@ and @Version@, with two values each:
--
--     @[{\"Stage\":[\"Test\",\"Deploy\"]},{\"Version\":[\"1\",\"2\"]}]@
--
--     The results of this query could include the following.
--
--     -   An EC2 instance that has the following two tags:
--         @{\"Stage\":\"Deploy\"}@, and @{\"Version\":\"2\"}@
--
--     -   An S3 bucket that has the following two tags:
--         @{\"Stage\":\"Test\"}@, and @{\"Version\":\"1\"}@
--
--     The query would not include the following items in the results,
--     however.
--
--     -   An EC2 instance that has only the following tag:
--         @{\"Stage\":\"Deploy\"}@.
--
--         The instance does not have __all__ of the tag keys specified in
--         the filter, so it is excluded from the results.
--
--     -   An RDS database that has the following two tags:
--         @{\"Stage\":\"Archived\"}@ and @{\"Version\":\"4\"}@
--
--         The database has all of the tag keys, but none of those keys has
--         an associated value that matches at least one of the specified
--         values in the filter.
--
-- 'query', 'resourceQuery_searchQuery' - The query that defines a group or a search.
newResourceQuery ::
  -- | 'type''
  QueryType ->
  -- | 'query'
  Prelude.Text ->
  ResourceQuery
newResourceQuery :: QueryType -> Text -> ResourceQuery
newResourceQuery QueryType
pType_ Text
pSearchQuery_ =
  ResourceQuery'
    { $sel:type':ResourceQuery' :: QueryType
type' = QueryType
pType_,
      $sel:query:ResourceQuery' :: Text
query = Text
pSearchQuery_
    }

-- | The type of the query. You can use the following values:
--
-- -   /@CLOUDFORMATION_STACK_1_0:@/ Specifies that the @Query@ contains an
--     ARN for a CloudFormation stack.
--
-- -   /@TAG_FILTERS_1_0:@/ Specifies that the @Query@ parameter contains a
--     JSON string that represents a collection of simple tag filters for
--     resource types and tags. The JSON string uses a syntax similar to
--     the
--     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html GetResources>@ @
--     operation, but uses only the
--     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html#resourcegrouptagging-GetResources-request-ResourceTypeFilters ResourceTypeFilters>@ @
--     and
--     @ @<https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html#resourcegrouptagging-GetResources-request-TagFiltersTagFilters TagFilters>@ @
--     fields. If you specify more than one tag key, only resources that
--     match all tag keys, and at least one value of each specified tag
--     key, are returned in your query. If you specify more than one value
--     for a tag key, a resource matches the filter if it has a tag key
--     value that matches /any/ of the specified values.
--
--     For example, consider the following sample query for resources that
--     have two tags, @Stage@ and @Version@, with two values each:
--
--     @[{\"Stage\":[\"Test\",\"Deploy\"]},{\"Version\":[\"1\",\"2\"]}]@
--
--     The results of this query could include the following.
--
--     -   An EC2 instance that has the following two tags:
--         @{\"Stage\":\"Deploy\"}@, and @{\"Version\":\"2\"}@
--
--     -   An S3 bucket that has the following two tags:
--         @{\"Stage\":\"Test\"}@, and @{\"Version\":\"1\"}@
--
--     The query would not include the following items in the results,
--     however.
--
--     -   An EC2 instance that has only the following tag:
--         @{\"Stage\":\"Deploy\"}@.
--
--         The instance does not have __all__ of the tag keys specified in
--         the filter, so it is excluded from the results.
--
--     -   An RDS database that has the following two tags:
--         @{\"Stage\":\"Archived\"}@ and @{\"Version\":\"4\"}@
--
--         The database has all of the tag keys, but none of those keys has
--         an associated value that matches at least one of the specified
--         values in the filter.
resourceQuery_type :: Lens.Lens' ResourceQuery QueryType
resourceQuery_type :: Lens' ResourceQuery QueryType
resourceQuery_type = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\ResourceQuery' {QueryType
type' :: QueryType
$sel:type':ResourceQuery' :: ResourceQuery -> QueryType
type'} -> QueryType
type') (\s :: ResourceQuery
s@ResourceQuery' {} QueryType
a -> ResourceQuery
s {$sel:type':ResourceQuery' :: QueryType
type' = QueryType
a} :: ResourceQuery)

-- | The query that defines a group or a search.
resourceQuery_searchQuery :: Lens.Lens' ResourceQuery Prelude.Text
resourceQuery_searchQuery :: Lens' ResourceQuery Text
resourceQuery_searchQuery = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\ResourceQuery' {Text
query :: Text
$sel:query:ResourceQuery' :: ResourceQuery -> Text
query} -> Text
query) (\s :: ResourceQuery
s@ResourceQuery' {} Text
a -> ResourceQuery
s {$sel:query:ResourceQuery' :: Text
query = Text
a} :: ResourceQuery)

instance Data.FromJSON ResourceQuery where
  parseJSON :: Value -> Parser ResourceQuery
parseJSON =
    forall a. String -> (Object -> Parser a) -> Value -> Parser a
Data.withObject
      String
"ResourceQuery"
      ( \Object
x ->
          QueryType -> Text -> ResourceQuery
ResourceQuery'
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> (Object
x forall a. FromJSON a => Object -> Key -> Parser a
Data..: Key
"Type")
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (Object
x forall a. FromJSON a => Object -> Key -> Parser a
Data..: Key
"Query")
      )

instance Prelude.Hashable ResourceQuery where
  hashWithSalt :: Int -> ResourceQuery -> Int
hashWithSalt Int
_salt ResourceQuery' {Text
QueryType
query :: Text
type' :: QueryType
$sel:query:ResourceQuery' :: ResourceQuery -> Text
$sel:type':ResourceQuery' :: ResourceQuery -> QueryType
..} =
    Int
_salt
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` QueryType
type'
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` Text
query

instance Prelude.NFData ResourceQuery where
  rnf :: ResourceQuery -> ()
rnf ResourceQuery' {Text
QueryType
query :: Text
type' :: QueryType
$sel:query:ResourceQuery' :: ResourceQuery -> Text
$sel:type':ResourceQuery' :: ResourceQuery -> QueryType
..} =
    forall a. NFData a => a -> ()
Prelude.rnf QueryType
type' seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Text
query

instance Data.ToJSON ResourceQuery where
  toJSON :: ResourceQuery -> Value
toJSON ResourceQuery' {Text
QueryType
query :: Text
type' :: QueryType
$sel:query:ResourceQuery' :: ResourceQuery -> Text
$sel:type':ResourceQuery' :: ResourceQuery -> QueryType
..} =
    [Pair] -> Value
Data.object
      ( forall a. [Maybe a] -> [a]
Prelude.catMaybes
          [ forall a. a -> Maybe a
Prelude.Just (Key
"Type" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
Data..= QueryType
type'),
            forall a. a -> Maybe a
Prelude.Just (Key
"Query" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
Data..= Text
query)
          ]
      )