<gh_stars>0
from uuid import uuid4
import yfinance as yf

from src.app.domain.collections.companies.companiesDatabaseUtility import *
import src.app.domain.collections.companies.companiesQueries as companyQueries

from src.app.database.utility import SqlUtility
from src.app.database.utility.ObjectComparisonUtility import *
from src.app.database.utility.QueryExceptions import InvalidRequest
from src.app.database.utility.QueryExceptions import RedundantUpdateException


def getAllCompanies():
    request = companyQueries.getAllCompaniesWithoutBusinessSummary()
    tuples = SqlUtility.executeSelectRequest(request)
    withBusinessSummary = False
    responseObject = parseTuplesAsCompanyList(tuples, withBusinessSummary)

    return responseObject


def getCompanyById(companyId):
    request = companyQueries.getFullCompanyById(companyId)
    queryResponse = SqlUtility.executeSelectRequest(request)
    if queryResponse == ():
        raise InvalidRequest("There is no company with this ID")
    responseTuple = queryResponse[0]

    withBusinessSummary = True
    responseObject = parseTuplesAsCompanyObject(responseTuple, withBusinessSummary)

    return responseObject


def getCompanyIdFromLongName(companyLongName):
    request = companyQueries.getCompanyIdFromLongName(companyLongName)
    queryResponse = SqlUtility.executeSelectRequest(request)

    if queryResponse == ():
        raise InvalidRequest("There is no company with this ID")

    responseTuple = queryResponse[0][0]
    return responseTuple


def createCompanyWithTickerAggregateAsObject(companyTickerAggregate):
    try:
        tickerAggregate = companyTickerAggregate['id']
    except Exception:
        raise InvalidRequest('Provided post body does not include the required ID attribute')
    companyIdAsObject, yFinanceTickerObject = createCompanyFromTickerAggregate(tickerAggregate)
    return {'id': str(companyIdAsObject)}


def createCompanyFromTickerAggregate(companyTickerAggregate):
    try:
        tickerObject = yf.Ticker(companyTickerAggregate).info
    except Exception:
        raise InvalidRequest('Provided ticker is not supported or is invalid')

    try:
        existingCompanyId = getCompanyIdFromLongName(tickerObject['longName'])
        return existingCompanyId, tickerObject

    except InvalidRequest:
        return createCompanyFromYFinanceTickerObject(tickerObject)


def createCompanyFromYFinanceTickerObject(yFinanceTickerObject):
    companyObject = parseYFinanceTickerObjectAsCompanyObjectWithoutId(yFinanceTickerObject)
    companyIdAsObject = createCompany(companyObject)
    return companyIdAsObject['id'], yFinanceTickerObject


def createCompany(companyObject):
    companyUUID = uuid4()
    return createCompanyWithUUIDAndCompanyObject(companyUUID, companyObject)


def createCompanyWithUUIDAndCompanyObject(companyUUID, companyObject):
    validateCompanyObject(companyObject)

    request = companyQueries.insertCompany(companyUUID, companyObject)
    insertedRowCount = SqlUtility.executeInsertRequest(request)

    if insertedRowCount != 1:
        raise InvalidRequest('Company creation failed (server error or duplicate error occurred)')

    return {'id': str(companyUUID)}


def updateCompanyById(companyId, companyObject):
    validateCompanyObject(companyObject)

    matchingCompanyInDatabase = getCompanyById(companyId)
    updateString = extractDivergingFieldsBetweenObjects(companyObject, matchingCompanyInDatabase)

    if updateString == '':
        raise RedundantUpdateException('The provided object is the same as target object')

    request = companyQueries.updateCompanyById(companyId, updateString)
    updatedRowCount = SqlUtility.executeUpdateRequest(request)

    return updatedRowCount


def deleteCompanyById(companyId):
    request = companyQueries.deleteCompanyById(companyId)
    deletedRowCount = SqlUtility.executeDeleteRequest(request)

    if deletedRowCount == 0:
        raise InvalidRequest('No match was found for Id or matching object has dependencies')

    return deletedRowCount
