#!/usr/bin/env python3

import time
from flask import url_for
from .util import live_server_setup, extract_UUID_from_client, wait_for_all_checks, delete_all_watches
import os


def set_response_with_ldjson(datastore_path):
    test_return_data = """<html>
       <body>
     Some initial text<br>
     <p>Which is across multiple lines</p>
     <br>
     So let's see what happens.  <br>
     <div class="sametext">Some text thats the same</div>
     <div class="changetext">Some text that will change</div>
     <script type="application/ld+json">
        {
           "@context":"https://schema.org/",
           "@type":"Product",
           "@id":"https://www.some-virtual-phone-shop.com/celular-iphone-14/p",
           "name":"Celular Iphone 14 Pro Max 256Gb E Sim A16 Bionic",
           "brand":{
              "@type":"Brand",
              "name":"APPLE"
           },
           "image":"https://www.some-virtual-phone-shop.com/15509426/image.jpg",
           "description":"You dont need it",
           "mpn":"111111",
           "sku":"22222",
           "Offers":{
              "@type":"AggregateOffer",
              "lowPrice":8097000,
              "highPrice":8099900,
              "priceCurrency":"COP",
              "offers":[
                 {
                    "@type":"Offer",
                    "price":8097000,
                    "priceCurrency":"COP",
                    "availability":"http://schema.org/InStock",
                    "sku":"102375961",
                    "itemCondition":"http://schema.org/NewCondition",
                    "seller":{
                       "@type":"Organization",
                       "name":"ajax"
                    }
                 }
              ],
              "offerCount":1
           }
        }
       </script>
     </body>
     </html>
"""

    with open(os.path.join(datastore_path, "endpoint-content.txt"), "w") as f:
        f.write(test_return_data)
    return None

def set_response_without_ldjson(datastore_path):
    test_return_data = """<html>
       <body>
     Some initial text<br>
     <p>Which is across multiple lines</p>
     <br>
     So let's see what happens.  <br>
     <div class="sametext">Some text thats the same</div>
     <div class="changetext">Some text that will change</div>     
     </body>
     </html>
"""

    with open(os.path.join(datastore_path, "endpoint-content.txt"), "w") as f:
        f.write(test_return_data)
    return None

# def test_setup(client, live_server, measure_memory_usage, datastore_path):
   #  live_server_setup(live_server) # Setup on conftest per function

# actually only really used by the distll.io importer, but could be handy too
def test_check_ldjson_price_autodetect(client, live_server, measure_memory_usage, datastore_path):
    
    set_response_with_ldjson(datastore_path=datastore_path)

    # Add our URL to the import page
    test_url = url_for('test_endpoint', _external=True)
    uuid = client.application.config.get('DATASTORE').add_watch(url=test_url)
    client.post(url_for("ui.form_watch_checknow"), follow_redirects=True)
    wait_for_all_checks(client)

    # Should get a notice that it's available
    res = client.get(url_for("watchlist.index"))
    assert b'ldjson-price-track-offer' in res.data

    # Accept it
    client.get(url_for('price_data_follower.accept', uuid=uuid, follow_redirects=True))
    client.post(url_for("ui.form_watch_checknow"), follow_redirects=True)
    wait_for_all_checks(client)
    # Offer should be gone
    res = client.get(url_for("watchlist.index"))
    assert b'Embedded price data' not in res.data
    assert b'processor-badge-restock_diff' in res.data

    # The processor badge should be a link that filters the watchlist by processor (?processor=restock_diff).
    # The "processor=restock_diff" string only appears in a rendered badge link's href (not in the injected
    # <style> block, which contains rules for every processor regardless of which watches are shown), so it's
    # a reliable marker for whether the restock watch's row is actually present.
    assert b'processor=restock_diff' in res.data, "Processor badge must link to a processor filter"

    # Filtering by the watch's own processor should keep its row (and badge link) visible
    res = client.get(url_for("watchlist.index", processor='restock_diff'))
    assert res.status_code == 200
    assert b'processor=restock_diff' in res.data, "Watch must remain visible when filtering by its processor"

    # Filtering by a different processor should hide this watch's row entirely
    res = client.get(url_for("watchlist.index", processor='text_json_diff'))
    assert res.status_code == 200
    assert b'processor=restock_diff' not in res.data, "Watch must be filtered out when its processor doesn't match"

    # and last snapshop (via API) should be just the price
    api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
    res = client.get(
        url_for("watchsinglehistory", uuid=uuid, timestamp='latest'),
        headers={'x-api-key': api_key},
    )

    assert b'8097000' in res.data

    # And not this cause its not the ld-json
    assert b"So let's see what happens" not in res.data

    delete_all_watches(client)

    ##########################################################################################
    # And we shouldnt see the offer
    set_response_without_ldjson(datastore_path=datastore_path)

    # Add our URL to the import page
    test_url = url_for('test_endpoint', _external=True)
    uuid = client.application.config.get('DATASTORE').add_watch(url=test_url)
    client.post(url_for("ui.form_watch_checknow"), follow_redirects=True)
    wait_for_all_checks(client)
    res = client.get(url_for("watchlist.index"))
    assert b'ldjson-price-track-offer' not in res.data
    
    ##########################################################################################
    delete_all_watches(client)


def _test_runner_check_bad_format_ignored(live_server, client, has_ldjson_price_data):

    test_url = url_for('test_endpoint', _external=True)
    uuid = client.application.config.get('DATASTORE').add_watch(url=test_url)
    client.post(url_for("ui.form_watch_checknow"), follow_redirects=True)
    wait_for_all_checks(client)

    for k,v in client.application.config.get('DATASTORE').data['watching'].items():
        assert v.get('last_error') == False
        assert v.get('has_ldjson_price_data') == has_ldjson_price_data, f"Detected LDJSON data? should be {has_ldjson_price_data}"


    ##########################################################################################
    delete_all_watches(client)


def test_bad_ldjson_is_correctly_ignored(client, live_server, measure_memory_usage, datastore_path):
    
    test_return_data = """
            <html>
            <head>
                <script type="application/ld+json">
                    {
                        "@context": "http://schema.org",
                        "@type": ["Product", "SubType"],
                        "name": "My test product",
                        "description": "",
                        "offers": {
                            "note" : "You can see the case-insensitive OffERS key, it should work",
                            "@type": "Offer",
                            "offeredBy": {
                                "@type": "Organization",
                                "name":"Person",
                                "telephone":"+1 999 999 999"
                            },
                            "price": "1",
                            "priceCurrency": "EUR",
                            "url": "/some/url"
                        }
                    }
                </script>
            </head>
            <body>
            <div class="yes">Some extra stuff</div>
            </body></html>
     """
    with open(os.path.join(datastore_path, "endpoint-content.txt"), "w") as f:
        f.write(test_return_data)

    _test_runner_check_bad_format_ignored(live_server=live_server, client=client, has_ldjson_price_data=True)

    # This is OK that it offers a suggestion in this case, the processor will let them know more about something wrong

    # test_return_data = """
    #         <html>
    #         <head>
    #             <script type="application/ld+json">
    #                 {
    #                     "@context": "http://schema.org",
    #                     "@type": ["Product", "SubType"],
    #                     "name": "My test product",
    #                     "description": "",
    #                     "BrokenOffers": {
    #                         "@type": "Offer",
    #                         "offeredBy": {
    #                             "@type": "Organization",
    #                             "name":"Person",
    #                             "telephone":"+1 999 999 999"
    #                         },
    #                         "price": "1",
    #                         "priceCurrency": "EUR",
    #                         "url": "/some/url"
    #                     }
    #                 }
    #             </script>
    #         </head>
    #         <body>
    #         <div class="yes">Some extra stuff</div>
    #         </body></html>
    #  """
    # with open(os.path.join(datastore_path, "endpoint-content.txt"), "w") as f:
    #     f.write(test_return_data)
    #
    # _test_runner_check_bad_format_ignored(live_server=live_server, client=client, has_ldjson_price_data=False)
