#
# Copyright (C) 2017 The Android Open Source Project
#
# 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 __future__ import print_function

import textwrap
import unittest
import xml.etree.ElementPath

import build.extract_manifest


class ExtractMinSdkVersionTest(unittest.TestCase):
    def testMinSdkVersion(self) -> None:
        xml_str = textwrap.dedent(
            """\
            <?xml version="1.0" encoding="utf-8"?>
            <manifest
                xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <application
                android:label="@string/app_name"
                android:debuggable="true">
                <activity
                  android:name=".Test"
                  android:label="@string/app_name">
                </activity>
              </application>
              <uses-sdk android:minSdkVersion="9"/>
            </manifest>
            """
        )
        root = xml.etree.ElementTree.fromstring(xml_str)

        self.assertEqual("9", build.extract_manifest.get_minsdkversion(root))

    def testUsesSdkMissingMinSdkVersion(self) -> None:
        xml_str = textwrap.dedent(
            """\
            <?xml version="1.0" encoding="utf-8"?>
            <manifest
                xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <application
                android:label="@string/app_name"
                android:debuggable="true">
                <activity
                  android:name=".Test"
                  android:label="@string/app_name">
                </activity>
              </application>
              <uses-sdk android:maxSdkVersion="21"/>
            </manifest>
            """
        )
        root = xml.etree.ElementTree.fromstring(xml_str)

        self.assertEqual("", build.extract_manifest.get_minsdkversion(root))

    def testNoUsesSdk(self) -> None:
        xml_str = textwrap.dedent(
            """\
            <?xml version="1.0" encoding="utf-8"?>
            <manifest
                xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <application
                android:label="@string/app_name"
                android:debuggable="true">
                <activity
                  android:name=".Test"
                  android:label="@string/app_name">
                </activity>
              </application>
            </manifest>
            """
        )
        root = xml.etree.ElementTree.fromstring(xml_str)

        self.assertEqual("", build.extract_manifest.get_minsdkversion(root))


class ExtractDebuggableTest(unittest.TestCase):
    def testIsDebuggable(self) -> None:
        xml_str = textwrap.dedent(
            """\
            <?xml version="1.0" encoding="utf-8"?>
            <manifest
                xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <application
                android:label="@string/app_name"
                android:debuggable="true">
              </application>
            </manifest>
            """
        )
        root = xml.etree.ElementTree.fromstring(xml_str)

        self.assertEqual("true", build.extract_manifest.get_debuggable(root))

    def testIsNotDebuggable(self) -> None:
        xml_str = textwrap.dedent(
            """\
            <?xml version="1.0" encoding="utf-8"?>
            <manifest
                xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <application
                android:label="@string/app_name"
                android:debuggable="false">
              </application>
            </manifest>
            """
        )
        root = xml.etree.ElementTree.fromstring(xml_str)

        self.assertEqual("false", build.extract_manifest.get_debuggable(root))

    def testBogusValue(self) -> None:
        xml_str = textwrap.dedent(
            """\
            <?xml version="1.0" encoding="utf-8"?>
            <manifest
                xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <application
                android:label="@string/app_name"
                android:debuggable="bogus">
              </application>
            </manifest>
            """
        )
        root = xml.etree.ElementTree.fromstring(xml_str)

        self.assertEqual("false", build.extract_manifest.get_debuggable(root))

    def testNotSet(self) -> None:
        xml_str = textwrap.dedent(
            """\
            <?xml version="1.0" encoding="utf-8"?>
            <manifest
                xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <application android:label="@string/app_name">
                <activity
                  android:name=".Test"
                  android:label="@string/app_name">
                </activity>
              </application>
              <uses-sdk android:maxSdkVersion="21"/>
            </manifest>
            """
        )
        root = xml.etree.ElementTree.fromstring(xml_str)

        self.assertEqual("false", build.extract_manifest.get_debuggable(root))
