# coding=utf-8
#
# 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.
#

from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

import io
import platform
import sys
import unittest

import mock

from apache_beam.testing.test_pipeline import TestPipeline
from apache_beam.testing.util import assert_that
from apache_beam.testing.util import equal_to

from . import pardo


def check_plants(actual):
  # [START plants]
  plants = [
      '🍓Strawberry',
      '🥕Carrot',
      '🍆Eggplant',
      '🍅Tomato',
      '🥔Potato',
  ]
  # [END plants]
  assert_that(actual, equal_to(plants))


def check_dofn_params(actual):
  # pylint: disable=line-too-long
  dofn_params = '\n'.join('''[START dofn_params]
# timestamp
type(timestamp) -> <class 'apache_beam.utils.timestamp.Timestamp'>
timestamp.micros -> 1584675660000000
timestamp.to_rfc3339() -> '2020-03-20T03:41:00Z'
timestamp.to_utc_datetime() -> datetime.datetime(2020, 3, 20, 3, 41)

# window
type(window) -> <class 'apache_beam.transforms.window.IntervalWindow'>
window.start -> Timestamp(1584675660) (2020-03-20 03:41:00)
window.end -> Timestamp(1584675690) (2020-03-20 03:41:30)
window.max_timestamp() -> Timestamp(1584675689.999999) (2020-03-20 03:41:29.999999)
[END dofn_params]'''.splitlines()[1:-1])
  # pylint: enable=line-too-long
  assert_that(actual, equal_to([dofn_params]))


def check_dofn_methods(actual):
  # Return the expected stdout to check the ordering of the called methods.
  return '''[START results]
__init__
setup
start_bundle
* process: 🍓
* process: 🥕
* process: 🍆
* process: 🍅
* process: 🥔
* finish_bundle: 🌱🌳🌍
teardown
[END results]'''.splitlines()[1:-1]


@mock.patch('apache_beam.Pipeline', TestPipeline)
# pylint: disable=line-too-long
@mock.patch('apache_beam.examples.snippets.transforms.element_wise.pardo.print', lambda elem: elem)
# pylint: enable=line-too-long
class ParDoTest(unittest.TestCase):
  def test_pardo_dofn(self):
    pardo.pardo_dofn(check_plants)

  # TODO: Remove this after Python 2 deprecation.
  # https://issues.apache.org/jira/browse/BEAM-8124
  @unittest.skipIf(sys.version_info[0] < 3 and platform.system() == 'Windows',
                   'Python 2 on Windows uses `long` rather than `int`')
  def test_pardo_dofn_params(self):
    pardo.pardo_dofn_params(check_dofn_params)


@mock.patch('apache_beam.Pipeline', TestPipeline)
@mock.patch('sys.stdout', new_callable=io.StringIO)
class ParDoStdoutTest(unittest.TestCase):
  def test_pardo_dofn_methods(self, mock_stdout):
    expected = pardo.pardo_dofn_methods(check_dofn_methods)
    actual = mock_stdout.getvalue().splitlines()

    # For the stdout, check the ordering of the methods, not of the elements.
    actual_stdout = [line.split(':')[0] for line in actual]
    expected_stdout = [line.split(':')[0] for line in expected]
    self.assertEqual(actual_stdout, expected_stdout)

    # For the elements, ignore the stdout and just make sure all elements match.
    actual_elements = {line for line in actual if line.startswith('*')}
    expected_elements = {line for line in expected if line.startswith('*')}
    self.assertEqual(actual_elements, expected_elements)


if __name__ == '__main__':
  unittest.main()
