# Copyright 2022 Planet Labs, PBC.
#
# Licensed 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.
from contextlib import nullcontext as does_not_raise

from click.exceptions import BadParameter
import pytest

from planet.cli import types


@pytest.mark.parametrize("input,expectation, expected",
                         [('a', does_not_raise(), ['a']),
                          ('a,b', does_not_raise(), ['a', 'b']),
                          ('a, b', does_not_raise(), ['a', 'b']),
                          ('a,,', pytest.raises(BadParameter), None),
                          ('', pytest.raises(BadParameter), None),
                          (['a'], does_not_raise(), ['a'])])  # yapf: disable
def test_cli_CommaSeparatedString(input, expectation, expected):
    with expectation:
        res = types.CommaSeparatedString().convert(input, None, None)

    if expected:
        assert res == expected


@pytest.mark.parametrize("input, expectation, expected",
                         [
                             ('1.0', does_not_raise(), [1.0]),
                             ('1,2.5', does_not_raise(), [1.0, 2.5]),
                             ('1, 2.5', does_not_raise(), [1.0, 2.5]),
                             ('foo, bar', pytest.raises(BadParameter), None),
                             ('1,,', pytest.raises(BadParameter), None),
                             ([1.0, 2.0], does_not_raise(), [1.0, 2.0]),
                         ])
def test_cli_CommaSeparatedFloat(input, expectation, expected):
    with expectation:
        res = types.CommaSeparatedFloat().convert(input, None, None)

    if expected:
        assert res == expected


parametrize_json = pytest.mark.parametrize("input, expectation, expected", [
    ('{"a":["b", "c"], "c":5}', does_not_raise(), {'a': ['b', 'c'], 'c': 5}),
    ('["b", {"c":5}]', does_not_raise(), ['b', {'c': 5}]),
    ('{"a":"b", foo:bar}', pytest.raises(BadParameter), None),
    ('{}', pytest.raises(BadParameter), None),
])


@parametrize_json
def test_cli_JSON_str(input, expectation, expected):
    with expectation:
        res = types.JSON().convert(input, None, None)

    if expected:
        assert res == expected


@parametrize_json
def test_cli_JSON_file_content(input, expectation, expected, tmp_path):
    filename = tmp_path / 'temp.json'
    with open(filename, 'w') as fp:
        fp.write(input)

    with expectation:
        res = types.JSON().convert(str(filename), None, None)

    if expected:
        assert res == expected


def test_cli_JSON_file_doesnotexist():
    with pytest.raises(BadParameter):
        types.JSON().convert('nonexistant.json', None, None)

@@ -628,16 +628,77 @@
 t_raise%0A
+import json%0A%0Aimport click%0Afrom click.testing import CliRunner
 %0Afrom cl
@@ -2192,16 +2192,1051 @@
 ected%0A%0A%0A
+@pytest.fixture(params=%5B%22stdin%22, %22str%22, %22file%22%5D)%0Adef json_input_test_params(request, write_to_tmp_json_file):%0A%0A    def _func(input_json):%0A        if request.param == 'file':%0A            filename = write_to_tmp_json_file(input_json, 'tmp.json')%0A            arg = str(filename)%0A            input = None%0A        elif request.param == 'str':%0A            arg = json.dumps(input_json)%0A            input = None%0A        elif request.param == 'stdin':%0A            arg = '-'%0A            input = json.dumps(input_json)%0A%0A        return arg, input%0A%0A    return _func%0A%0A%0Adef test_cli_JSON_inputs(json_input_test_params):%0A    %22%22%22Confirm that file, stdin, and str inputs are all supported%22%22%22%0A%0A    @click.option('--foo', type=types.JSON())%0A    @click.command()%0A    def test(foo):%0A        click.echo(json.dumps(foo))%0A%0A    test_json = %7B'a': 'b'%7D%0A    arg, input = json_input_test_params(test_json)%0A    result = CliRunner().invoke(test, args=%5Bf'--foo=%7Barg%7D'%5D, input=input)%0A    assert result.exit_code == 0%0A    assert json.loads(result.output) == test_json%0A%0A%0A
 parametr
@@ -3262,32 +3262,37 @@
 ark.parametrize(
+%0A    
 %22input, expectat
@@ -3306,19 +3306,27 @@
 pected%22,
- %5B%0A
+%0A    %5B%0A    
     ('%7B%22
@@ -3348,16 +3348,25 @@
 %22c%22:5%7D',
+%0A        
  does_no
@@ -3377,16 +3377,30 @@
 ise(), %7B
+%0A             
 'a': %5B'b
@@ -3418,12 +3418,26 @@
 ': 5
-%7D),%0A
+%0A         %7D),%0A    
     
@@ -3484,19 +3484,45 @@
 ', %7B
-'c': 5
+%0A            'c': 5%0A        
 %7D%5D),%0A
+    
     
@@ -3576,24 +3576,28 @@
 er), None),%0A
+    
     ('%7B%7D', p
@@ -3631,16 +3631,20 @@
  None),%0A
+    
 %5D)%0A%0A%0A@pa

test JSON type file, str, and stdin input types